PackageManagerService.java revision cb8e31d0d06fc80b926b658d38161d7f50c3cfee
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.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 28import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 29import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 30import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 31import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 32import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 33import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 34import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 35import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 36import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 37import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 38import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 39import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 40import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 41import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 42import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 43import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 44import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 45import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 46import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 47import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 48import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 49import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 50import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 51import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 52import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 53import static android.content.pm.PackageManager.INSTALL_INTERNAL; 54import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 55import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 56import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 59import static android.content.pm.PackageManager.MATCH_ALL; 60import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 61import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 62import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 63import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 64import static android.content.pm.PackageManager.PERMISSION_DENIED; 65import static android.content.pm.PackageManager.PERMISSION_GRANTED; 66import static android.content.pm.PackageParser.isApkFile; 67import static android.os.Process.PACKAGE_INFO_GID; 68import static android.os.Process.SYSTEM_UID; 69import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 70import static android.system.OsConstants.O_CREAT; 71import static android.system.OsConstants.O_RDWR; 72import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 73import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER; 74import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 75import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 76import static com.android.internal.util.ArrayUtils.appendInt; 77import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 78import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 79import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 80import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 81import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 82import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 83import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 84import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 85 86import android.Manifest; 87import android.app.ActivityManager; 88import android.app.ActivityManagerNative; 89import android.app.AppGlobals; 90import android.app.IActivityManager; 91import android.app.admin.IDevicePolicyManager; 92import android.app.backup.IBackupManager; 93import android.app.usage.UsageStats; 94import android.app.usage.UsageStatsManager; 95import android.content.BroadcastReceiver; 96import android.content.ComponentName; 97import android.content.Context; 98import android.content.IIntentReceiver; 99import android.content.Intent; 100import android.content.IntentFilter; 101import android.content.IntentSender; 102import android.content.IntentSender.SendIntentException; 103import android.content.ServiceConnection; 104import android.content.pm.ActivityInfo; 105import android.content.pm.ApplicationInfo; 106import android.content.pm.FeatureInfo; 107import android.content.pm.IOnPermissionsChangeListener; 108import android.content.pm.IPackageDataObserver; 109import android.content.pm.IPackageDeleteObserver; 110import android.content.pm.IPackageDeleteObserver2; 111import android.content.pm.IPackageInstallObserver2; 112import android.content.pm.IPackageInstaller; 113import android.content.pm.IPackageManager; 114import android.content.pm.IPackageMoveObserver; 115import android.content.pm.IPackageStatsObserver; 116import android.content.pm.InstrumentationInfo; 117import android.content.pm.IntentFilterVerificationInfo; 118import android.content.pm.KeySet; 119import android.content.pm.ManifestDigest; 120import android.content.pm.PackageCleanItem; 121import android.content.pm.PackageInfo; 122import android.content.pm.PackageInfoLite; 123import android.content.pm.PackageInstaller; 124import android.content.pm.PackageManager; 125import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 126import android.content.pm.PackageManagerInternal; 127import android.content.pm.PackageParser; 128import android.content.pm.PackageParser.ActivityIntentInfo; 129import android.content.pm.PackageParser.PackageLite; 130import android.content.pm.PackageParser.PackageParserException; 131import android.content.pm.PackageStats; 132import android.content.pm.PackageUserState; 133import android.content.pm.ParceledListSlice; 134import android.content.pm.PermissionGroupInfo; 135import android.content.pm.PermissionInfo; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.pm.Signature; 140import android.content.pm.UserInfo; 141import android.content.pm.VerificationParams; 142import android.content.pm.VerifierDeviceIdentity; 143import android.content.pm.VerifierInfo; 144import android.content.res.Resources; 145import android.hardware.display.DisplayManager; 146import android.net.Uri; 147import android.os.Debug; 148import android.os.Binder; 149import android.os.Build; 150import android.os.Bundle; 151import android.os.Environment; 152import android.os.Environment.UserEnvironment; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.Looper; 157import android.os.Message; 158import android.os.Parcel; 159import android.os.ParcelFileDescriptor; 160import android.os.Process; 161import android.os.RemoteCallbackList; 162import android.os.RemoteException; 163import android.os.SELinux; 164import android.os.ServiceManager; 165import android.os.SystemClock; 166import android.os.SystemProperties; 167import android.os.Trace; 168import android.os.UserHandle; 169import android.os.UserManager; 170import android.os.storage.IMountService; 171import android.os.storage.MountServiceInternal; 172import android.os.storage.StorageEventListener; 173import android.os.storage.StorageManager; 174import android.os.storage.VolumeInfo; 175import android.os.storage.VolumeRecord; 176import android.security.KeyStore; 177import android.security.SystemKeyStore; 178import android.system.ErrnoException; 179import android.system.Os; 180import android.system.StructStat; 181import android.text.TextUtils; 182import android.text.format.DateUtils; 183import android.util.ArrayMap; 184import android.util.ArraySet; 185import android.util.AtomicFile; 186import android.util.DisplayMetrics; 187import android.util.EventLog; 188import android.util.ExceptionUtils; 189import android.util.Log; 190import android.util.LogPrinter; 191import android.util.MathUtils; 192import android.util.PrintStreamPrinter; 193import android.util.Slog; 194import android.util.SparseArray; 195import android.util.SparseBooleanArray; 196import android.util.SparseIntArray; 197import android.util.Xml; 198import android.view.Display; 199 200import dalvik.system.DexFile; 201import dalvik.system.VMRuntime; 202 203import libcore.io.IoUtils; 204import libcore.util.EmptyArray; 205 206import com.android.internal.R; 207import com.android.internal.annotations.GuardedBy; 208import com.android.internal.app.IMediaContainerService; 209import com.android.internal.app.ResolverActivity; 210import com.android.internal.content.NativeLibraryHelper; 211import com.android.internal.content.PackageHelper; 212import com.android.internal.os.IParcelFileDescriptorFactory; 213import com.android.internal.os.SomeArgs; 214import com.android.internal.os.Zygote; 215import com.android.internal.util.ArrayUtils; 216import com.android.internal.util.FastPrintWriter; 217import com.android.internal.util.FastXmlSerializer; 218import com.android.internal.util.IndentingPrintWriter; 219import com.android.internal.util.Preconditions; 220import com.android.server.EventLogTags; 221import com.android.server.FgThread; 222import com.android.server.IntentResolver; 223import com.android.server.LocalServices; 224import com.android.server.ServiceThread; 225import com.android.server.SystemConfig; 226import com.android.server.Watchdog; 227import com.android.server.pm.PermissionsState.PermissionState; 228import com.android.server.pm.Settings.DatabaseVersion; 229import com.android.server.pm.Settings.VersionInfo; 230import com.android.server.storage.DeviceStorageMonitorInternal; 231 232import org.xmlpull.v1.XmlPullParser; 233import org.xmlpull.v1.XmlPullParserException; 234import org.xmlpull.v1.XmlSerializer; 235 236import java.io.BufferedInputStream; 237import java.io.BufferedOutputStream; 238import java.io.BufferedReader; 239import java.io.ByteArrayInputStream; 240import java.io.ByteArrayOutputStream; 241import java.io.File; 242import java.io.FileDescriptor; 243import java.io.FileNotFoundException; 244import java.io.FileOutputStream; 245import java.io.FileReader; 246import java.io.FilenameFilter; 247import java.io.IOException; 248import java.io.InputStream; 249import java.io.PrintWriter; 250import java.nio.charset.StandardCharsets; 251import java.security.NoSuchAlgorithmException; 252import java.security.PublicKey; 253import java.security.cert.CertificateEncodingException; 254import java.security.cert.CertificateException; 255import java.text.SimpleDateFormat; 256import java.util.ArrayList; 257import java.util.Arrays; 258import java.util.Collection; 259import java.util.Collections; 260import java.util.Comparator; 261import java.util.Date; 262import java.util.Iterator; 263import java.util.List; 264import java.util.Map; 265import java.util.Objects; 266import java.util.Set; 267import java.util.concurrent.CountDownLatch; 268import java.util.concurrent.TimeUnit; 269import java.util.concurrent.atomic.AtomicBoolean; 270import java.util.concurrent.atomic.AtomicInteger; 271import java.util.concurrent.atomic.AtomicLong; 272 273/** 274 * Keep track of all those .apks everywhere. 275 * 276 * This is very central to the platform's security; please run the unit 277 * tests whenever making modifications here: 278 * 279runtest -c android.content.pm.PackageManagerTests frameworks-core 280 * 281 * {@hide} 282 */ 283public class PackageManagerService extends IPackageManager.Stub { 284 static final String TAG = "PackageManager"; 285 static final boolean DEBUG_SETTINGS = false; 286 static final boolean DEBUG_PREFERRED = false; 287 static final boolean DEBUG_UPGRADE = false; 288 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 289 private static final boolean DEBUG_BACKUP = false; 290 private static final boolean DEBUG_INSTALL = false; 291 private static final boolean DEBUG_REMOVE = false; 292 private static final boolean DEBUG_BROADCASTS = false; 293 private static final boolean DEBUG_SHOW_INFO = false; 294 private static final boolean DEBUG_PACKAGE_INFO = false; 295 private static final boolean DEBUG_INTENT_MATCHING = false; 296 private static final boolean DEBUG_PACKAGE_SCANNING = false; 297 private static final boolean DEBUG_VERIFY = false; 298 private static final boolean DEBUG_DEXOPT = false; 299 private static final boolean DEBUG_ABI_SELECTION = false; 300 301 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 302 303 private static final int RADIO_UID = Process.PHONE_UID; 304 private static final int LOG_UID = Process.LOG_UID; 305 private static final int NFC_UID = Process.NFC_UID; 306 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 307 private static final int SHELL_UID = Process.SHELL_UID; 308 309 // Cap the size of permission trees that 3rd party apps can define 310 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 311 312 // Suffix used during package installation when copying/moving 313 // package apks to install directory. 314 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 315 316 static final int SCAN_NO_DEX = 1<<1; 317 static final int SCAN_FORCE_DEX = 1<<2; 318 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 319 static final int SCAN_NEW_INSTALL = 1<<4; 320 static final int SCAN_NO_PATHS = 1<<5; 321 static final int SCAN_UPDATE_TIME = 1<<6; 322 static final int SCAN_DEFER_DEX = 1<<7; 323 static final int SCAN_BOOTING = 1<<8; 324 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 325 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 326 static final int SCAN_REPLACING = 1<<11; 327 static final int SCAN_REQUIRE_KNOWN = 1<<12; 328 static final int SCAN_MOVE = 1<<13; 329 static final int SCAN_INITIAL = 1<<14; 330 331 static final int REMOVE_CHATTY = 1<<16; 332 333 private static final int[] EMPTY_INT_ARRAY = new int[0]; 334 335 /** 336 * Timeout (in milliseconds) after which the watchdog should declare that 337 * our handler thread is wedged. The usual default for such things is one 338 * minute but we sometimes do very lengthy I/O operations on this thread, 339 * such as installing multi-gigabyte applications, so ours needs to be longer. 340 */ 341 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 342 343 /** 344 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 345 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 346 * settings entry if available, otherwise we use the hardcoded default. If it's been 347 * more than this long since the last fstrim, we force one during the boot sequence. 348 * 349 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 350 * one gets run at the next available charging+idle time. This final mandatory 351 * no-fstrim check kicks in only of the other scheduling criteria is never met. 352 */ 353 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 354 355 /** 356 * Whether verification is enabled by default. 357 */ 358 private static final boolean DEFAULT_VERIFY_ENABLE = true; 359 360 /** 361 * The default maximum time to wait for the verification agent to return in 362 * milliseconds. 363 */ 364 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 365 366 /** 367 * The default response for package verification timeout. 368 * 369 * This can be either PackageManager.VERIFICATION_ALLOW or 370 * PackageManager.VERIFICATION_REJECT. 371 */ 372 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 373 374 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 375 376 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 377 DEFAULT_CONTAINER_PACKAGE, 378 "com.android.defcontainer.DefaultContainerService"); 379 380 private static final String KILL_APP_REASON_GIDS_CHANGED = 381 "permission grant or revoke changed gids"; 382 383 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 384 "permissions revoked"; 385 386 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 387 388 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 389 390 /** Permission grant: not grant the permission. */ 391 private static final int GRANT_DENIED = 1; 392 393 /** Permission grant: grant the permission as an install permission. */ 394 private static final int GRANT_INSTALL = 2; 395 396 /** Permission grant: grant the permission as an install permission for a legacy app. */ 397 private static final int GRANT_INSTALL_LEGACY = 3; 398 399 /** Permission grant: grant the permission as a runtime one. */ 400 private static final int GRANT_RUNTIME = 4; 401 402 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 403 private static final int GRANT_UPGRADE = 5; 404 405 /** Canonical intent used to identify what counts as a "web browser" app */ 406 private static final Intent sBrowserIntent; 407 static { 408 sBrowserIntent = new Intent(); 409 sBrowserIntent.setAction(Intent.ACTION_VIEW); 410 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 411 sBrowserIntent.setData(Uri.parse("http:")); 412 } 413 414 final ServiceThread mHandlerThread; 415 416 final PackageHandler mHandler; 417 418 /** 419 * Messages for {@link #mHandler} that need to wait for system ready before 420 * being dispatched. 421 */ 422 private ArrayList<Message> mPostSystemReadyMessages; 423 424 final int mSdkVersion = Build.VERSION.SDK_INT; 425 426 final Context mContext; 427 final boolean mFactoryTest; 428 final boolean mOnlyCore; 429 final boolean mLazyDexOpt; 430 final long mDexOptLRUThresholdInMills; 431 final DisplayMetrics mMetrics; 432 final int mDefParseFlags; 433 final String[] mSeparateProcesses; 434 final boolean mIsUpgrade; 435 436 // This is where all application persistent data goes. 437 final File mAppDataDir; 438 439 // This is where all application persistent data goes for secondary users. 440 final File mUserAppDataDir; 441 442 /** The location for ASEC container files on internal storage. */ 443 final String mAsecInternalPath; 444 445 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 446 // LOCK HELD. Can be called with mInstallLock held. 447 @GuardedBy("mInstallLock") 448 final Installer mInstaller; 449 450 /** Directory where installed third-party apps stored */ 451 final File mAppInstallDir; 452 453 /** 454 * Directory to which applications installed internally have their 455 * 32 bit native libraries copied. 456 */ 457 private File mAppLib32InstallDir; 458 459 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 460 // apps. 461 final File mDrmAppPrivateInstallDir; 462 463 // ---------------------------------------------------------------- 464 465 // Lock for state used when installing and doing other long running 466 // operations. Methods that must be called with this lock held have 467 // the suffix "LI". 468 final Object mInstallLock = new Object(); 469 470 // ---------------------------------------------------------------- 471 472 // Keys are String (package name), values are Package. This also serves 473 // as the lock for the global state. Methods that must be called with 474 // this lock held have the prefix "LP". 475 @GuardedBy("mPackages") 476 final ArrayMap<String, PackageParser.Package> mPackages = 477 new ArrayMap<String, PackageParser.Package>(); 478 479 // Tracks available target package names -> overlay package paths. 480 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 481 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 482 483 /** 484 * Tracks new system packages [receiving in an OTA] that we expect to 485 * find updated user-installed versions. Keys are package name, values 486 * are package location. 487 */ 488 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 489 490 final Settings mSettings; 491 boolean mRestoredSettings; 492 493 // System configuration read by SystemConfig. 494 final int[] mGlobalGids; 495 final SparseArray<ArraySet<String>> mSystemPermissions; 496 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 497 498 // If mac_permissions.xml was found for seinfo labeling. 499 boolean mFoundPolicyFile; 500 501 // If a recursive restorecon of /data/data/<pkg> is needed. 502 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 503 504 public static final class SharedLibraryEntry { 505 public final String path; 506 public final String apk; 507 508 SharedLibraryEntry(String _path, String _apk) { 509 path = _path; 510 apk = _apk; 511 } 512 } 513 514 // Currently known shared libraries. 515 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 516 new ArrayMap<String, SharedLibraryEntry>(); 517 518 // All available activities, for your resolving pleasure. 519 final ActivityIntentResolver mActivities = 520 new ActivityIntentResolver(); 521 522 // All available receivers, for your resolving pleasure. 523 final ActivityIntentResolver mReceivers = 524 new ActivityIntentResolver(); 525 526 // All available services, for your resolving pleasure. 527 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 528 529 // All available providers, for your resolving pleasure. 530 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 531 532 // Mapping from provider base names (first directory in content URI codePath) 533 // to the provider information. 534 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 535 new ArrayMap<String, PackageParser.Provider>(); 536 537 // Mapping from instrumentation class names to info about them. 538 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 539 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 540 541 // Mapping from permission names to info about them. 542 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 543 new ArrayMap<String, PackageParser.PermissionGroup>(); 544 545 // Packages whose data we have transfered into another package, thus 546 // should no longer exist. 547 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 548 549 // Broadcast actions that are only available to the system. 550 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 551 552 /** List of packages waiting for verification. */ 553 final SparseArray<PackageVerificationState> mPendingVerification 554 = new SparseArray<PackageVerificationState>(); 555 556 /** Set of packages associated with each app op permission. */ 557 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 558 559 final PackageInstallerService mInstallerService; 560 561 private final PackageDexOptimizer mPackageDexOptimizer; 562 563 private AtomicInteger mNextMoveId = new AtomicInteger(); 564 private final MoveCallbacks mMoveCallbacks; 565 566 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 567 568 // Cache of users who need badging. 569 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 570 571 /** Token for keys in mPendingVerification. */ 572 private int mPendingVerificationToken = 0; 573 574 volatile boolean mSystemReady; 575 volatile boolean mSafeMode; 576 volatile boolean mHasSystemUidErrors; 577 578 ApplicationInfo mAndroidApplication; 579 final ActivityInfo mResolveActivity = new ActivityInfo(); 580 final ResolveInfo mResolveInfo = new ResolveInfo(); 581 ComponentName mResolveComponentName; 582 PackageParser.Package mPlatformPackage; 583 ComponentName mCustomResolverComponentName; 584 585 boolean mResolverReplaced = false; 586 587 private final ComponentName mIntentFilterVerifierComponent; 588 private int mIntentFilterVerificationToken = 0; 589 590 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 591 = new SparseArray<IntentFilterVerificationState>(); 592 593 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 594 new DefaultPermissionGrantPolicy(this); 595 596 private static class IFVerificationParams { 597 PackageParser.Package pkg; 598 boolean replacing; 599 int userId; 600 int verifierUid; 601 602 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 603 int _userId, int _verifierUid) { 604 pkg = _pkg; 605 replacing = _replacing; 606 userId = _userId; 607 replacing = _replacing; 608 verifierUid = _verifierUid; 609 } 610 } 611 612 private interface IntentFilterVerifier<T extends IntentFilter> { 613 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 614 T filter, String packageName); 615 void startVerifications(int userId); 616 void receiveVerificationResponse(int verificationId); 617 } 618 619 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 620 private Context mContext; 621 private ComponentName mIntentFilterVerifierComponent; 622 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 623 624 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 625 mContext = context; 626 mIntentFilterVerifierComponent = verifierComponent; 627 } 628 629 private String getDefaultScheme() { 630 return IntentFilter.SCHEME_HTTPS; 631 } 632 633 @Override 634 public void startVerifications(int userId) { 635 // Launch verifications requests 636 int count = mCurrentIntentFilterVerifications.size(); 637 for (int n=0; n<count; n++) { 638 int verificationId = mCurrentIntentFilterVerifications.get(n); 639 final IntentFilterVerificationState ivs = 640 mIntentFilterVerificationStates.get(verificationId); 641 642 String packageName = ivs.getPackageName(); 643 644 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 645 final int filterCount = filters.size(); 646 ArraySet<String> domainsSet = new ArraySet<>(); 647 for (int m=0; m<filterCount; m++) { 648 PackageParser.ActivityIntentInfo filter = filters.get(m); 649 domainsSet.addAll(filter.getHostsList()); 650 } 651 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 652 synchronized (mPackages) { 653 if (mSettings.createIntentFilterVerificationIfNeededLPw( 654 packageName, domainsList) != null) { 655 scheduleWriteSettingsLocked(); 656 } 657 } 658 sendVerificationRequest(userId, verificationId, ivs); 659 } 660 mCurrentIntentFilterVerifications.clear(); 661 } 662 663 private void sendVerificationRequest(int userId, int verificationId, 664 IntentFilterVerificationState ivs) { 665 666 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 667 verificationIntent.putExtra( 668 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 669 verificationId); 670 verificationIntent.putExtra( 671 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 672 getDefaultScheme()); 673 verificationIntent.putExtra( 674 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 675 ivs.getHostsString()); 676 verificationIntent.putExtra( 677 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 678 ivs.getPackageName()); 679 verificationIntent.setComponent(mIntentFilterVerifierComponent); 680 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 681 682 UserHandle user = new UserHandle(userId); 683 mContext.sendBroadcastAsUser(verificationIntent, user); 684 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 685 "Sending IntentFilter verification broadcast"); 686 } 687 688 public void receiveVerificationResponse(int verificationId) { 689 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 690 691 final boolean verified = ivs.isVerified(); 692 693 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 694 final int count = filters.size(); 695 if (DEBUG_DOMAIN_VERIFICATION) { 696 Slog.i(TAG, "Received verification response " + verificationId 697 + " for " + count + " filters, verified=" + verified); 698 } 699 for (int n=0; n<count; n++) { 700 PackageParser.ActivityIntentInfo filter = filters.get(n); 701 filter.setVerified(verified); 702 703 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 704 + " verified with result:" + verified + " and hosts:" 705 + ivs.getHostsString()); 706 } 707 708 mIntentFilterVerificationStates.remove(verificationId); 709 710 final String packageName = ivs.getPackageName(); 711 IntentFilterVerificationInfo ivi = null; 712 713 synchronized (mPackages) { 714 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 715 } 716 if (ivi == null) { 717 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 718 + verificationId + " packageName:" + packageName); 719 return; 720 } 721 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 722 "Updating IntentFilterVerificationInfo for package " + packageName 723 +" verificationId:" + verificationId); 724 725 synchronized (mPackages) { 726 if (verified) { 727 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 728 } else { 729 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 730 } 731 scheduleWriteSettingsLocked(); 732 733 final int userId = ivs.getUserId(); 734 if (userId != UserHandle.USER_ALL) { 735 final int userStatus = 736 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 737 738 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 739 boolean needUpdate = false; 740 741 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 742 // already been set by the User thru the Disambiguation dialog 743 switch (userStatus) { 744 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 745 if (verified) { 746 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 747 } else { 748 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 749 } 750 needUpdate = true; 751 break; 752 753 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 754 if (verified) { 755 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 756 needUpdate = true; 757 } 758 break; 759 760 default: 761 // Nothing to do 762 } 763 764 if (needUpdate) { 765 mSettings.updateIntentFilterVerificationStatusLPw( 766 packageName, updatedStatus, userId); 767 scheduleWritePackageRestrictionsLocked(userId); 768 } 769 } 770 } 771 } 772 773 @Override 774 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 775 ActivityIntentInfo filter, String packageName) { 776 if (!hasValidDomains(filter)) { 777 return false; 778 } 779 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 780 if (ivs == null) { 781 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 782 packageName); 783 } 784 if (DEBUG_DOMAIN_VERIFICATION) { 785 Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter); 786 } 787 ivs.addFilter(filter); 788 return true; 789 } 790 791 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 792 int userId, int verificationId, String packageName) { 793 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 794 verifierUid, userId, packageName); 795 ivs.setPendingState(); 796 synchronized (mPackages) { 797 mIntentFilterVerificationStates.append(verificationId, ivs); 798 mCurrentIntentFilterVerifications.add(verificationId); 799 } 800 return ivs; 801 } 802 } 803 804 private static boolean hasValidDomains(ActivityIntentInfo filter) { 805 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 806 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 807 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 808 } 809 810 private IntentFilterVerifier mIntentFilterVerifier; 811 812 // Set of pending broadcasts for aggregating enable/disable of components. 813 static class PendingPackageBroadcasts { 814 // for each user id, a map of <package name -> components within that package> 815 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 816 817 public PendingPackageBroadcasts() { 818 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 819 } 820 821 public ArrayList<String> get(int userId, String packageName) { 822 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 823 return packages.get(packageName); 824 } 825 826 public void put(int userId, String packageName, ArrayList<String> components) { 827 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 828 packages.put(packageName, components); 829 } 830 831 public void remove(int userId, String packageName) { 832 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 833 if (packages != null) { 834 packages.remove(packageName); 835 } 836 } 837 838 public void remove(int userId) { 839 mUidMap.remove(userId); 840 } 841 842 public int userIdCount() { 843 return mUidMap.size(); 844 } 845 846 public int userIdAt(int n) { 847 return mUidMap.keyAt(n); 848 } 849 850 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 851 return mUidMap.get(userId); 852 } 853 854 public int size() { 855 // total number of pending broadcast entries across all userIds 856 int num = 0; 857 for (int i = 0; i< mUidMap.size(); i++) { 858 num += mUidMap.valueAt(i).size(); 859 } 860 return num; 861 } 862 863 public void clear() { 864 mUidMap.clear(); 865 } 866 867 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 868 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 869 if (map == null) { 870 map = new ArrayMap<String, ArrayList<String>>(); 871 mUidMap.put(userId, map); 872 } 873 return map; 874 } 875 } 876 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 877 878 // Service Connection to remote media container service to copy 879 // package uri's from external media onto secure containers 880 // or internal storage. 881 private IMediaContainerService mContainerService = null; 882 883 static final int SEND_PENDING_BROADCAST = 1; 884 static final int MCS_BOUND = 3; 885 static final int END_COPY = 4; 886 static final int INIT_COPY = 5; 887 static final int MCS_UNBIND = 6; 888 static final int START_CLEANING_PACKAGE = 7; 889 static final int FIND_INSTALL_LOC = 8; 890 static final int POST_INSTALL = 9; 891 static final int MCS_RECONNECT = 10; 892 static final int MCS_GIVE_UP = 11; 893 static final int UPDATED_MEDIA_STATUS = 12; 894 static final int WRITE_SETTINGS = 13; 895 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 896 static final int PACKAGE_VERIFIED = 15; 897 static final int CHECK_PENDING_VERIFICATION = 16; 898 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 899 static final int INTENT_FILTER_VERIFIED = 18; 900 901 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 902 903 // Delay time in millisecs 904 static final int BROADCAST_DELAY = 10 * 1000; 905 906 static UserManagerService sUserManager; 907 908 // Stores a list of users whose package restrictions file needs to be updated 909 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 910 911 final private DefaultContainerConnection mDefContainerConn = 912 new DefaultContainerConnection(); 913 class DefaultContainerConnection implements ServiceConnection { 914 public void onServiceConnected(ComponentName name, IBinder service) { 915 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 916 IMediaContainerService imcs = 917 IMediaContainerService.Stub.asInterface(service); 918 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 919 } 920 921 public void onServiceDisconnected(ComponentName name) { 922 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 923 } 924 } 925 926 // Recordkeeping of restore-after-install operations that are currently in flight 927 // between the Package Manager and the Backup Manager 928 class PostInstallData { 929 public InstallArgs args; 930 public PackageInstalledInfo res; 931 932 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 933 args = _a; 934 res = _r; 935 } 936 } 937 938 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 939 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 940 941 // XML tags for backup/restore of various bits of state 942 private static final String TAG_PREFERRED_BACKUP = "pa"; 943 private static final String TAG_DEFAULT_APPS = "da"; 944 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 945 946 final String mRequiredVerifierPackage; 947 final String mRequiredInstallerPackage; 948 949 private final PackageUsage mPackageUsage = new PackageUsage(); 950 951 private class PackageUsage { 952 private static final int WRITE_INTERVAL 953 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 954 955 private final Object mFileLock = new Object(); 956 private final AtomicLong mLastWritten = new AtomicLong(0); 957 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 958 959 private boolean mIsHistoricalPackageUsageAvailable = true; 960 961 boolean isHistoricalPackageUsageAvailable() { 962 return mIsHistoricalPackageUsageAvailable; 963 } 964 965 void write(boolean force) { 966 if (force) { 967 writeInternal(); 968 return; 969 } 970 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 971 && !DEBUG_DEXOPT) { 972 return; 973 } 974 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 975 new Thread("PackageUsage_DiskWriter") { 976 @Override 977 public void run() { 978 try { 979 writeInternal(); 980 } finally { 981 mBackgroundWriteRunning.set(false); 982 } 983 } 984 }.start(); 985 } 986 } 987 988 private void writeInternal() { 989 synchronized (mPackages) { 990 synchronized (mFileLock) { 991 AtomicFile file = getFile(); 992 FileOutputStream f = null; 993 try { 994 f = file.startWrite(); 995 BufferedOutputStream out = new BufferedOutputStream(f); 996 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 997 StringBuilder sb = new StringBuilder(); 998 for (PackageParser.Package pkg : mPackages.values()) { 999 if (pkg.mLastPackageUsageTimeInMills == 0) { 1000 continue; 1001 } 1002 sb.setLength(0); 1003 sb.append(pkg.packageName); 1004 sb.append(' '); 1005 sb.append((long)pkg.mLastPackageUsageTimeInMills); 1006 sb.append('\n'); 1007 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 1008 } 1009 out.flush(); 1010 file.finishWrite(f); 1011 } catch (IOException e) { 1012 if (f != null) { 1013 file.failWrite(f); 1014 } 1015 Log.e(TAG, "Failed to write package usage times", e); 1016 } 1017 } 1018 } 1019 mLastWritten.set(SystemClock.elapsedRealtime()); 1020 } 1021 1022 void readLP() { 1023 synchronized (mFileLock) { 1024 AtomicFile file = getFile(); 1025 BufferedInputStream in = null; 1026 try { 1027 in = new BufferedInputStream(file.openRead()); 1028 StringBuffer sb = new StringBuffer(); 1029 while (true) { 1030 String packageName = readToken(in, sb, ' '); 1031 if (packageName == null) { 1032 break; 1033 } 1034 String timeInMillisString = readToken(in, sb, '\n'); 1035 if (timeInMillisString == null) { 1036 throw new IOException("Failed to find last usage time for package " 1037 + packageName); 1038 } 1039 PackageParser.Package pkg = mPackages.get(packageName); 1040 if (pkg == null) { 1041 continue; 1042 } 1043 long timeInMillis; 1044 try { 1045 timeInMillis = Long.parseLong(timeInMillisString.toString()); 1046 } catch (NumberFormatException e) { 1047 throw new IOException("Failed to parse " + timeInMillisString 1048 + " as a long.", e); 1049 } 1050 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1051 } 1052 } catch (FileNotFoundException expected) { 1053 mIsHistoricalPackageUsageAvailable = false; 1054 } catch (IOException e) { 1055 Log.w(TAG, "Failed to read package usage times", e); 1056 } finally { 1057 IoUtils.closeQuietly(in); 1058 } 1059 } 1060 mLastWritten.set(SystemClock.elapsedRealtime()); 1061 } 1062 1063 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1064 throws IOException { 1065 sb.setLength(0); 1066 while (true) { 1067 int ch = in.read(); 1068 if (ch == -1) { 1069 if (sb.length() == 0) { 1070 return null; 1071 } 1072 throw new IOException("Unexpected EOF"); 1073 } 1074 if (ch == endOfToken) { 1075 return sb.toString(); 1076 } 1077 sb.append((char)ch); 1078 } 1079 } 1080 1081 private AtomicFile getFile() { 1082 File dataDir = Environment.getDataDirectory(); 1083 File systemDir = new File(dataDir, "system"); 1084 File fname = new File(systemDir, "package-usage.list"); 1085 return new AtomicFile(fname); 1086 } 1087 } 1088 1089 class PackageHandler extends Handler { 1090 private boolean mBound = false; 1091 final ArrayList<HandlerParams> mPendingInstalls = 1092 new ArrayList<HandlerParams>(); 1093 1094 private boolean connectToService() { 1095 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1096 " DefaultContainerService"); 1097 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1098 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1099 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1100 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 1101 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1102 mBound = true; 1103 return true; 1104 } 1105 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1106 return false; 1107 } 1108 1109 private void disconnectService() { 1110 mContainerService = null; 1111 mBound = false; 1112 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1113 mContext.unbindService(mDefContainerConn); 1114 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1115 } 1116 1117 PackageHandler(Looper looper) { 1118 super(looper); 1119 } 1120 1121 public void handleMessage(Message msg) { 1122 try { 1123 doHandleMessage(msg); 1124 } finally { 1125 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1126 } 1127 } 1128 1129 void doHandleMessage(Message msg) { 1130 switch (msg.what) { 1131 case INIT_COPY: { 1132 HandlerParams params = (HandlerParams) msg.obj; 1133 int idx = mPendingInstalls.size(); 1134 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1135 // If a bind was already initiated we dont really 1136 // need to do anything. The pending install 1137 // will be processed later on. 1138 if (!mBound) { 1139 try { 1140 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindMCS", 1141 System.identityHashCode(params)); 1142 // If this is the only one pending we might 1143 // have to bind to the service again. 1144 if (!connectToService()) { 1145 Slog.e(TAG, "Failed to bind to media container service"); 1146 params.serviceError(); 1147 return; 1148 } else { 1149 // Once we bind to the service, the first 1150 // pending request will be processed. 1151 mPendingInstalls.add(idx, params); 1152 } 1153 } finally { 1154 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindMCS", 1155 System.identityHashCode(params)); 1156 } 1157 } else { 1158 mPendingInstalls.add(idx, params); 1159 // Already bound to the service. Just make 1160 // sure we trigger off processing the first request. 1161 if (idx == 0) { 1162 mHandler.sendEmptyMessage(MCS_BOUND); 1163 } 1164 } 1165 break; 1166 } 1167 case MCS_BOUND: { 1168 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1169 if (msg.obj != null) { 1170 mContainerService = (IMediaContainerService) msg.obj; 1171 } 1172 if (mContainerService == null) { 1173 if (!mBound) { 1174 // Something seriously wrong since we are not bound and we are not 1175 // waiting for connection. Bail out. 1176 Slog.e(TAG, "Cannot bind to media container service"); 1177 for (HandlerParams params : mPendingInstalls) { 1178 // Indicate service bind error 1179 params.serviceError(); 1180 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1181 System.identityHashCode(params)); 1182 } 1183 mPendingInstalls.clear(); 1184 } else { 1185 Slog.w(TAG, "Waiting to connect to media container service"); 1186 } 1187 } else if (mPendingInstalls.size() > 0) { 1188 HandlerParams params = mPendingInstalls.get(0); 1189 if (params != null) { 1190 if (params.startCopy()) { 1191 // We are done... look for more work or to 1192 // go idle. 1193 if (DEBUG_SD_INSTALL) Log.i(TAG, 1194 "Checking for more work or unbind..."); 1195 // Delete pending install 1196 if (mPendingInstalls.size() > 0) { 1197 mPendingInstalls.remove(0); 1198 } 1199 if (mPendingInstalls.size() == 0) { 1200 if (mBound) { 1201 if (DEBUG_SD_INSTALL) Log.i(TAG, 1202 "Posting delayed MCS_UNBIND"); 1203 removeMessages(MCS_UNBIND); 1204 Message ubmsg = obtainMessage(MCS_UNBIND); 1205 // Unbind after a little delay, to avoid 1206 // continual thrashing. 1207 sendMessageDelayed(ubmsg, 10000); 1208 } 1209 } else { 1210 // There are more pending requests in queue. 1211 // Just post MCS_BOUND message to trigger processing 1212 // of next pending install. 1213 if (DEBUG_SD_INSTALL) Log.i(TAG, 1214 "Posting MCS_BOUND for next work"); 1215 mHandler.sendEmptyMessage(MCS_BOUND); 1216 } 1217 } 1218 } 1219 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1220 System.identityHashCode(params)); 1221 } else { 1222 // Should never happen ideally. 1223 Slog.w(TAG, "Empty queue"); 1224 } 1225 break; 1226 } 1227 case MCS_RECONNECT: { 1228 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1229 if (mPendingInstalls.size() > 0) { 1230 if (mBound) { 1231 disconnectService(); 1232 } 1233 if (!connectToService()) { 1234 Slog.e(TAG, "Failed to bind to media container service"); 1235 for (HandlerParams params : mPendingInstalls) { 1236 // Indicate service bind error 1237 params.serviceError(); 1238 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1239 System.identityHashCode(params)); 1240 } 1241 mPendingInstalls.clear(); 1242 } 1243 } 1244 break; 1245 } 1246 case MCS_UNBIND: { 1247 // If there is no actual work left, then time to unbind. 1248 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1249 1250 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1251 if (mBound) { 1252 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1253 1254 disconnectService(); 1255 } 1256 } else if (mPendingInstalls.size() > 0) { 1257 // There are more pending requests in queue. 1258 // Just post MCS_BOUND message to trigger processing 1259 // of next pending install. 1260 mHandler.sendEmptyMessage(MCS_BOUND); 1261 } 1262 1263 break; 1264 } 1265 case MCS_GIVE_UP: { 1266 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1267 HandlerParams params = mPendingInstalls.remove(0); 1268 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1269 System.identityHashCode(params)); 1270 break; 1271 } 1272 case SEND_PENDING_BROADCAST: { 1273 String packages[]; 1274 ArrayList<String> components[]; 1275 int size = 0; 1276 int uids[]; 1277 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1278 synchronized (mPackages) { 1279 if (mPendingBroadcasts == null) { 1280 return; 1281 } 1282 size = mPendingBroadcasts.size(); 1283 if (size <= 0) { 1284 // Nothing to be done. Just return 1285 return; 1286 } 1287 packages = new String[size]; 1288 components = new ArrayList[size]; 1289 uids = new int[size]; 1290 int i = 0; // filling out the above arrays 1291 1292 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1293 int packageUserId = mPendingBroadcasts.userIdAt(n); 1294 Iterator<Map.Entry<String, ArrayList<String>>> it 1295 = mPendingBroadcasts.packagesForUserId(packageUserId) 1296 .entrySet().iterator(); 1297 while (it.hasNext() && i < size) { 1298 Map.Entry<String, ArrayList<String>> ent = it.next(); 1299 packages[i] = ent.getKey(); 1300 components[i] = ent.getValue(); 1301 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1302 uids[i] = (ps != null) 1303 ? UserHandle.getUid(packageUserId, ps.appId) 1304 : -1; 1305 i++; 1306 } 1307 } 1308 size = i; 1309 mPendingBroadcasts.clear(); 1310 } 1311 // Send broadcasts 1312 for (int i = 0; i < size; i++) { 1313 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1314 } 1315 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1316 break; 1317 } 1318 case START_CLEANING_PACKAGE: { 1319 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1320 final String packageName = (String)msg.obj; 1321 final int userId = msg.arg1; 1322 final boolean andCode = msg.arg2 != 0; 1323 synchronized (mPackages) { 1324 if (userId == UserHandle.USER_ALL) { 1325 int[] users = sUserManager.getUserIds(); 1326 for (int user : users) { 1327 mSettings.addPackageToCleanLPw( 1328 new PackageCleanItem(user, packageName, andCode)); 1329 } 1330 } else { 1331 mSettings.addPackageToCleanLPw( 1332 new PackageCleanItem(userId, packageName, andCode)); 1333 } 1334 } 1335 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1336 startCleaningPackages(); 1337 } break; 1338 case POST_INSTALL: { 1339 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1340 PostInstallData data = mRunningInstalls.get(msg.arg1); 1341 mRunningInstalls.delete(msg.arg1); 1342 boolean deleteOld = false; 1343 1344 if (data != null) { 1345 InstallArgs args = data.args; 1346 PackageInstalledInfo res = data.res; 1347 1348 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1349 final String packageName = res.pkg.applicationInfo.packageName; 1350 res.removedInfo.sendBroadcast(false, true, false); 1351 Bundle extras = new Bundle(1); 1352 extras.putInt(Intent.EXTRA_UID, res.uid); 1353 1354 // Now that we successfully installed the package, grant runtime 1355 // permissions if requested before broadcasting the install. 1356 if ((args.installFlags 1357 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { 1358 grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(), 1359 args.installGrantPermissions); 1360 } 1361 1362 // Determine the set of users who are adding this 1363 // package for the first time vs. those who are seeing 1364 // an update. 1365 int[] firstUsers; 1366 int[] updateUsers = new int[0]; 1367 if (res.origUsers == null || res.origUsers.length == 0) { 1368 firstUsers = res.newUsers; 1369 } else { 1370 firstUsers = new int[0]; 1371 for (int i=0; i<res.newUsers.length; i++) { 1372 int user = res.newUsers[i]; 1373 boolean isNew = true; 1374 for (int j=0; j<res.origUsers.length; j++) { 1375 if (res.origUsers[j] == user) { 1376 isNew = false; 1377 break; 1378 } 1379 } 1380 if (isNew) { 1381 int[] newFirst = new int[firstUsers.length+1]; 1382 System.arraycopy(firstUsers, 0, newFirst, 0, 1383 firstUsers.length); 1384 newFirst[firstUsers.length] = user; 1385 firstUsers = newFirst; 1386 } else { 1387 int[] newUpdate = new int[updateUsers.length+1]; 1388 System.arraycopy(updateUsers, 0, newUpdate, 0, 1389 updateUsers.length); 1390 newUpdate[updateUsers.length] = user; 1391 updateUsers = newUpdate; 1392 } 1393 } 1394 } 1395 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1396 packageName, extras, null, null, firstUsers); 1397 final boolean update = res.removedInfo.removedPackage != null; 1398 if (update) { 1399 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1400 } 1401 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1402 packageName, extras, null, null, updateUsers); 1403 if (update) { 1404 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1405 packageName, extras, null, null, updateUsers); 1406 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1407 null, null, packageName, null, updateUsers); 1408 1409 // treat asec-hosted packages like removable media on upgrade 1410 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1411 if (DEBUG_INSTALL) { 1412 Slog.i(TAG, "upgrading pkg " + res.pkg 1413 + " is ASEC-hosted -> AVAILABLE"); 1414 } 1415 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1416 ArrayList<String> pkgList = new ArrayList<String>(1); 1417 pkgList.add(packageName); 1418 sendResourcesChangedBroadcast(true, true, 1419 pkgList,uidArray, null); 1420 } 1421 } 1422 if (res.removedInfo.args != null) { 1423 // Remove the replaced package's older resources safely now 1424 deleteOld = true; 1425 } 1426 1427 // If this app is a browser and it's newly-installed for some 1428 // users, clear any default-browser state in those users 1429 if (firstUsers.length > 0) { 1430 // the app's nature doesn't depend on the user, so we can just 1431 // check its browser nature in any user and generalize. 1432 if (packageIsBrowser(packageName, firstUsers[0])) { 1433 synchronized (mPackages) { 1434 for (int userId : firstUsers) { 1435 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1436 } 1437 } 1438 } 1439 } 1440 // Log current value of "unknown sources" setting 1441 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1442 getUnknownSourcesSettings()); 1443 } 1444 // Force a gc to clear up things 1445 Runtime.getRuntime().gc(); 1446 // We delete after a gc for applications on sdcard. 1447 if (deleteOld) { 1448 synchronized (mInstallLock) { 1449 res.removedInfo.args.doPostDeleteLI(true); 1450 } 1451 } 1452 if (args.observer != null) { 1453 try { 1454 Bundle extras = extrasForInstallResult(res); 1455 args.observer.onPackageInstalled(res.name, res.returnCode, 1456 res.returnMsg, extras); 1457 } catch (RemoteException e) { 1458 Slog.i(TAG, "Observer no longer exists."); 1459 } 1460 } 1461 } else { 1462 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1463 } 1464 1465 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1466 } break; 1467 case UPDATED_MEDIA_STATUS: { 1468 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1469 boolean reportStatus = msg.arg1 == 1; 1470 boolean doGc = msg.arg2 == 1; 1471 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1472 if (doGc) { 1473 // Force a gc to clear up stale containers. 1474 Runtime.getRuntime().gc(); 1475 } 1476 if (msg.obj != null) { 1477 @SuppressWarnings("unchecked") 1478 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1479 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1480 // Unload containers 1481 unloadAllContainers(args); 1482 } 1483 if (reportStatus) { 1484 try { 1485 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1486 PackageHelper.getMountService().finishMediaUpdate(); 1487 } catch (RemoteException e) { 1488 Log.e(TAG, "MountService not running?"); 1489 } 1490 } 1491 } break; 1492 case WRITE_SETTINGS: { 1493 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1494 synchronized (mPackages) { 1495 removeMessages(WRITE_SETTINGS); 1496 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1497 mSettings.writeLPr(); 1498 mDirtyUsers.clear(); 1499 } 1500 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1501 } break; 1502 case WRITE_PACKAGE_RESTRICTIONS: { 1503 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1504 synchronized (mPackages) { 1505 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1506 for (int userId : mDirtyUsers) { 1507 mSettings.writePackageRestrictionsLPr(userId); 1508 } 1509 mDirtyUsers.clear(); 1510 } 1511 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1512 } break; 1513 case CHECK_PENDING_VERIFICATION: { 1514 final int verificationId = msg.arg1; 1515 final PackageVerificationState state = mPendingVerification.get(verificationId); 1516 1517 if ((state != null) && !state.timeoutExtended()) { 1518 final InstallArgs args = state.getInstallArgs(); 1519 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1520 1521 Slog.i(TAG, "Verification timed out for " + originUri); 1522 mPendingVerification.remove(verificationId); 1523 1524 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1525 1526 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1527 Slog.i(TAG, "Continuing with installation of " + originUri); 1528 state.setVerifierResponse(Binder.getCallingUid(), 1529 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1530 broadcastPackageVerified(verificationId, originUri, 1531 PackageManager.VERIFICATION_ALLOW, 1532 state.getInstallArgs().getUser()); 1533 try { 1534 ret = args.copyApk(mContainerService, true); 1535 } catch (RemoteException e) { 1536 Slog.e(TAG, "Could not contact the ContainerService"); 1537 } 1538 } else { 1539 broadcastPackageVerified(verificationId, originUri, 1540 PackageManager.VERIFICATION_REJECT, 1541 state.getInstallArgs().getUser()); 1542 } 1543 1544 processPendingInstall(args, ret); 1545 mHandler.sendEmptyMessage(MCS_UNBIND); 1546 } 1547 Trace.asyncTraceEnd( 1548 TRACE_TAG_PACKAGE_MANAGER, "pendingVerification", verificationId); 1549 break; 1550 } 1551 case PACKAGE_VERIFIED: { 1552 final int verificationId = msg.arg1; 1553 1554 final PackageVerificationState state = mPendingVerification.get(verificationId); 1555 if (state == null) { 1556 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1557 break; 1558 } 1559 1560 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1561 1562 state.setVerifierResponse(response.callerUid, response.code); 1563 1564 if (state.isVerificationComplete()) { 1565 mPendingVerification.remove(verificationId); 1566 1567 final InstallArgs args = state.getInstallArgs(); 1568 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1569 1570 int ret; 1571 if (state.isInstallAllowed()) { 1572 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1573 broadcastPackageVerified(verificationId, originUri, 1574 response.code, state.getInstallArgs().getUser()); 1575 try { 1576 ret = args.copyApk(mContainerService, true); 1577 } catch (RemoteException e) { 1578 Slog.e(TAG, "Could not contact the ContainerService"); 1579 } 1580 } else { 1581 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1582 } 1583 1584 processPendingInstall(args, ret); 1585 1586 mHandler.sendEmptyMessage(MCS_UNBIND); 1587 } 1588 1589 break; 1590 } 1591 case START_INTENT_FILTER_VERIFICATIONS: { 1592 IFVerificationParams params = (IFVerificationParams) msg.obj; 1593 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1594 params.replacing, params.pkg); 1595 break; 1596 } 1597 case INTENT_FILTER_VERIFIED: { 1598 final int verificationId = msg.arg1; 1599 1600 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1601 verificationId); 1602 if (state == null) { 1603 Slog.w(TAG, "Invalid IntentFilter verification token " 1604 + verificationId + " received"); 1605 break; 1606 } 1607 1608 final int userId = state.getUserId(); 1609 1610 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1611 "Processing IntentFilter verification with token:" 1612 + verificationId + " and userId:" + userId); 1613 1614 final IntentFilterVerificationResponse response = 1615 (IntentFilterVerificationResponse) msg.obj; 1616 1617 state.setVerifierResponse(response.callerUid, response.code); 1618 1619 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1620 "IntentFilter verification with token:" + verificationId 1621 + " and userId:" + userId 1622 + " is settings verifier response with response code:" 1623 + response.code); 1624 1625 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1626 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1627 + response.getFailedDomainsString()); 1628 } 1629 1630 if (state.isVerificationComplete()) { 1631 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1632 } else { 1633 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1634 "IntentFilter verification with token:" + verificationId 1635 + " was not said to be complete"); 1636 } 1637 1638 break; 1639 } 1640 } 1641 } 1642 } 1643 1644 private StorageEventListener mStorageListener = new StorageEventListener() { 1645 @Override 1646 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1647 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1648 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1649 final String volumeUuid = vol.getFsUuid(); 1650 1651 // Clean up any users or apps that were removed or recreated 1652 // while this volume was missing 1653 reconcileUsers(volumeUuid); 1654 reconcileApps(volumeUuid); 1655 1656 // Clean up any install sessions that expired or were 1657 // cancelled while this volume was missing 1658 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1659 1660 loadPrivatePackages(vol); 1661 1662 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1663 unloadPrivatePackages(vol); 1664 } 1665 } 1666 1667 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1668 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1669 updateExternalMediaStatus(true, false); 1670 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1671 updateExternalMediaStatus(false, false); 1672 } 1673 } 1674 } 1675 1676 @Override 1677 public void onVolumeForgotten(String fsUuid) { 1678 if (TextUtils.isEmpty(fsUuid)) { 1679 Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1680 return; 1681 } 1682 1683 // Remove any apps installed on the forgotten volume 1684 synchronized (mPackages) { 1685 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1686 for (PackageSetting ps : packages) { 1687 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1688 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1689 UserHandle.USER_OWNER, PackageManager.DELETE_ALL_USERS); 1690 } 1691 1692 mSettings.onVolumeForgotten(fsUuid); 1693 mSettings.writeLPr(); 1694 } 1695 } 1696 }; 1697 1698 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId, 1699 String[] grantedPermissions) { 1700 if (userId >= UserHandle.USER_OWNER) { 1701 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1702 } else if (userId == UserHandle.USER_ALL) { 1703 final int[] userIds; 1704 synchronized (mPackages) { 1705 userIds = UserManagerService.getInstance().getUserIds(); 1706 } 1707 for (int someUserId : userIds) { 1708 grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions); 1709 } 1710 } 1711 1712 // We could have touched GID membership, so flush out packages.list 1713 synchronized (mPackages) { 1714 mSettings.writePackageListLPr(); 1715 } 1716 } 1717 1718 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1719 String[] grantedPermissions) { 1720 SettingBase sb = (SettingBase) pkg.mExtras; 1721 if (sb == null) { 1722 return; 1723 } 1724 1725 PermissionsState permissionsState = sb.getPermissionsState(); 1726 1727 for (String permission : pkg.requestedPermissions) { 1728 BasePermission bp = mSettings.mPermissions.get(permission); 1729 if (bp != null && bp.isRuntime() && (grantedPermissions == null 1730 || ArrayUtils.contains(grantedPermissions, permission))) { 1731 permissionsState.grantRuntimePermission(bp, userId); 1732 } 1733 } 1734 } 1735 1736 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1737 Bundle extras = null; 1738 switch (res.returnCode) { 1739 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1740 extras = new Bundle(); 1741 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1742 res.origPermission); 1743 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1744 res.origPackage); 1745 break; 1746 } 1747 case PackageManager.INSTALL_SUCCEEDED: { 1748 extras = new Bundle(); 1749 extras.putBoolean(Intent.EXTRA_REPLACING, 1750 res.removedInfo != null && res.removedInfo.removedPackage != null); 1751 break; 1752 } 1753 } 1754 return extras; 1755 } 1756 1757 void scheduleWriteSettingsLocked() { 1758 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1759 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1760 } 1761 } 1762 1763 void scheduleWritePackageRestrictionsLocked(int userId) { 1764 if (!sUserManager.exists(userId)) return; 1765 mDirtyUsers.add(userId); 1766 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1767 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1768 } 1769 } 1770 1771 public static PackageManagerService main(Context context, Installer installer, 1772 boolean factoryTest, boolean onlyCore) { 1773 PackageManagerService m = new PackageManagerService(context, installer, 1774 factoryTest, onlyCore); 1775 ServiceManager.addService("package", m); 1776 return m; 1777 } 1778 1779 static String[] splitString(String str, char sep) { 1780 int count = 1; 1781 int i = 0; 1782 while ((i=str.indexOf(sep, i)) >= 0) { 1783 count++; 1784 i++; 1785 } 1786 1787 String[] res = new String[count]; 1788 i=0; 1789 count = 0; 1790 int lastI=0; 1791 while ((i=str.indexOf(sep, i)) >= 0) { 1792 res[count] = str.substring(lastI, i); 1793 count++; 1794 i++; 1795 lastI = i; 1796 } 1797 res[count] = str.substring(lastI, str.length()); 1798 return res; 1799 } 1800 1801 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1802 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1803 Context.DISPLAY_SERVICE); 1804 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1805 } 1806 1807 public PackageManagerService(Context context, Installer installer, 1808 boolean factoryTest, boolean onlyCore) { 1809 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1810 SystemClock.uptimeMillis()); 1811 1812 if (mSdkVersion <= 0) { 1813 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1814 } 1815 1816 mContext = context; 1817 mFactoryTest = factoryTest; 1818 mOnlyCore = onlyCore; 1819 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1820 mMetrics = new DisplayMetrics(); 1821 mSettings = new Settings(mPackages); 1822 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1823 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1824 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1825 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1826 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1827 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1828 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1829 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1830 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1831 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1832 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1833 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1834 1835 // TODO: add a property to control this? 1836 long dexOptLRUThresholdInMinutes; 1837 if (mLazyDexOpt) { 1838 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1839 } else { 1840 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1841 } 1842 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1843 1844 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1845 if (separateProcesses != null && separateProcesses.length() > 0) { 1846 if ("*".equals(separateProcesses)) { 1847 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1848 mSeparateProcesses = null; 1849 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1850 } else { 1851 mDefParseFlags = 0; 1852 mSeparateProcesses = separateProcesses.split(","); 1853 Slog.w(TAG, "Running with debug.separate_processes: " 1854 + separateProcesses); 1855 } 1856 } else { 1857 mDefParseFlags = 0; 1858 mSeparateProcesses = null; 1859 } 1860 1861 mInstaller = installer; 1862 mPackageDexOptimizer = new PackageDexOptimizer(this); 1863 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 1864 1865 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 1866 FgThread.get().getLooper()); 1867 1868 getDefaultDisplayMetrics(context, mMetrics); 1869 1870 SystemConfig systemConfig = SystemConfig.getInstance(); 1871 mGlobalGids = systemConfig.getGlobalGids(); 1872 mSystemPermissions = systemConfig.getSystemPermissions(); 1873 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1874 1875 synchronized (mInstallLock) { 1876 // writer 1877 synchronized (mPackages) { 1878 mHandlerThread = new ServiceThread(TAG, 1879 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1880 mHandlerThread.start(); 1881 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1882 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1883 1884 File dataDir = Environment.getDataDirectory(); 1885 mAppDataDir = new File(dataDir, "data"); 1886 mAppInstallDir = new File(dataDir, "app"); 1887 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1888 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1889 mUserAppDataDir = new File(dataDir, "user"); 1890 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1891 1892 sUserManager = new UserManagerService(context, this, 1893 mInstallLock, mPackages); 1894 1895 // Propagate permission configuration in to package manager. 1896 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1897 = systemConfig.getPermissions(); 1898 for (int i=0; i<permConfig.size(); i++) { 1899 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1900 BasePermission bp = mSettings.mPermissions.get(perm.name); 1901 if (bp == null) { 1902 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1903 mSettings.mPermissions.put(perm.name, bp); 1904 } 1905 if (perm.gids != null) { 1906 bp.setGids(perm.gids, perm.perUser); 1907 } 1908 } 1909 1910 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1911 for (int i=0; i<libConfig.size(); i++) { 1912 mSharedLibraries.put(libConfig.keyAt(i), 1913 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1914 } 1915 1916 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1917 1918 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1919 mSdkVersion, mOnlyCore); 1920 1921 String customResolverActivity = Resources.getSystem().getString( 1922 R.string.config_customResolverActivity); 1923 if (TextUtils.isEmpty(customResolverActivity)) { 1924 customResolverActivity = null; 1925 } else { 1926 mCustomResolverComponentName = ComponentName.unflattenFromString( 1927 customResolverActivity); 1928 } 1929 1930 long startTime = SystemClock.uptimeMillis(); 1931 1932 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1933 startTime); 1934 1935 // Set flag to monitor and not change apk file paths when 1936 // scanning install directories. 1937 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 1938 1939 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1940 1941 /** 1942 * Add everything in the in the boot class path to the 1943 * list of process files because dexopt will have been run 1944 * if necessary during zygote startup. 1945 */ 1946 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1947 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1948 1949 if (bootClassPath != null) { 1950 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1951 for (String element : bootClassPathElements) { 1952 alreadyDexOpted.add(element); 1953 } 1954 } else { 1955 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1956 } 1957 1958 if (systemServerClassPath != null) { 1959 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1960 for (String element : systemServerClassPathElements) { 1961 alreadyDexOpted.add(element); 1962 } 1963 } else { 1964 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 1965 } 1966 1967 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 1968 final String[] dexCodeInstructionSets = 1969 getDexCodeInstructionSets( 1970 allInstructionSets.toArray(new String[allInstructionSets.size()])); 1971 1972 /** 1973 * Ensure all external libraries have had dexopt run on them. 1974 */ 1975 if (mSharedLibraries.size() > 0) { 1976 // NOTE: For now, we're compiling these system "shared libraries" 1977 // (and framework jars) into all available architectures. It's possible 1978 // to compile them only when we come across an app that uses them (there's 1979 // already logic for that in scanPackageLI) but that adds some complexity. 1980 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1981 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1982 final String lib = libEntry.path; 1983 if (lib == null) { 1984 continue; 1985 } 1986 1987 try { 1988 int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); 1989 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1990 alreadyDexOpted.add(lib); 1991 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 1992 } 1993 } catch (FileNotFoundException e) { 1994 Slog.w(TAG, "Library not found: " + lib); 1995 } catch (IOException e) { 1996 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1997 + e.getMessage()); 1998 } 1999 } 2000 } 2001 } 2002 2003 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2004 2005 // Gross hack for now: we know this file doesn't contain any 2006 // code, so don't dexopt it to avoid the resulting log spew. 2007 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 2008 2009 // Gross hack for now: we know this file is only part of 2010 // the boot class path for art, so don't dexopt it to 2011 // avoid the resulting log spew. 2012 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 2013 2014 /** 2015 * There are a number of commands implemented in Java, which 2016 * we currently need to do the dexopt on so that they can be 2017 * run from a non-root shell. 2018 */ 2019 String[] frameworkFiles = frameworkDir.list(); 2020 if (frameworkFiles != null) { 2021 // TODO: We could compile these only for the most preferred ABI. We should 2022 // first double check that the dex files for these commands are not referenced 2023 // by other system apps. 2024 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2025 for (int i=0; i<frameworkFiles.length; i++) { 2026 File libPath = new File(frameworkDir, frameworkFiles[i]); 2027 String path = libPath.getPath(); 2028 // Skip the file if we already did it. 2029 if (alreadyDexOpted.contains(path)) { 2030 continue; 2031 } 2032 // Skip the file if it is not a type we want to dexopt. 2033 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 2034 continue; 2035 } 2036 try { 2037 int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); 2038 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2039 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 2040 } 2041 } catch (FileNotFoundException e) { 2042 Slog.w(TAG, "Jar not found: " + path); 2043 } catch (IOException e) { 2044 Slog.w(TAG, "Exception reading jar: " + path, e); 2045 } 2046 } 2047 } 2048 } 2049 2050 // Collect vendor overlay packages. 2051 // (Do this before scanning any apps.) 2052 // For security and version matching reason, only consider 2053 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2054 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2055 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2056 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2057 2058 // Find base frameworks (resource packages without code). 2059 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2060 | PackageParser.PARSE_IS_SYSTEM_DIR 2061 | PackageParser.PARSE_IS_PRIVILEGED, 2062 scanFlags | SCAN_NO_DEX, 0); 2063 2064 // Collected privileged system packages. 2065 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2066 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2067 | PackageParser.PARSE_IS_SYSTEM_DIR 2068 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2069 2070 // Collect ordinary system packages. 2071 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2072 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2073 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2074 2075 // Collect all vendor packages. 2076 File vendorAppDir = new File("/vendor/app"); 2077 try { 2078 vendorAppDir = vendorAppDir.getCanonicalFile(); 2079 } catch (IOException e) { 2080 // failed to look up canonical path, continue with original one 2081 } 2082 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2083 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2084 2085 // Collect all OEM packages. 2086 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2087 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2088 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2089 2090 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 2091 mInstaller.moveFiles(); 2092 2093 // Prune any system packages that no longer exist. 2094 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2095 if (!mOnlyCore) { 2096 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2097 while (psit.hasNext()) { 2098 PackageSetting ps = psit.next(); 2099 2100 /* 2101 * If this is not a system app, it can't be a 2102 * disable system app. 2103 */ 2104 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2105 continue; 2106 } 2107 2108 /* 2109 * If the package is scanned, it's not erased. 2110 */ 2111 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2112 if (scannedPkg != null) { 2113 /* 2114 * If the system app is both scanned and in the 2115 * disabled packages list, then it must have been 2116 * added via OTA. Remove it from the currently 2117 * scanned package so the previously user-installed 2118 * application can be scanned. 2119 */ 2120 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2121 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2122 + ps.name + "; removing system app. Last known codePath=" 2123 + ps.codePathString + ", installStatus=" + ps.installStatus 2124 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2125 + scannedPkg.mVersionCode); 2126 removePackageLI(ps, true); 2127 mExpectingBetter.put(ps.name, ps.codePath); 2128 } 2129 2130 continue; 2131 } 2132 2133 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2134 psit.remove(); 2135 logCriticalInfo(Log.WARN, "System package " + ps.name 2136 + " no longer exists; wiping its data"); 2137 removeDataDirsLI(null, ps.name); 2138 } else { 2139 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2140 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2141 possiblyDeletedUpdatedSystemApps.add(ps.name); 2142 } 2143 } 2144 } 2145 } 2146 2147 //look for any incomplete package installations 2148 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2149 //clean up list 2150 for(int i = 0; i < deletePkgsList.size(); i++) { 2151 //clean up here 2152 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2153 } 2154 //delete tmp files 2155 deleteTempPackageFiles(); 2156 2157 // Remove any shared userIDs that have no associated packages 2158 mSettings.pruneSharedUsersLPw(); 2159 2160 if (!mOnlyCore) { 2161 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2162 SystemClock.uptimeMillis()); 2163 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2164 2165 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2166 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2167 2168 /** 2169 * Remove disable package settings for any updated system 2170 * apps that were removed via an OTA. If they're not a 2171 * previously-updated app, remove them completely. 2172 * Otherwise, just revoke their system-level permissions. 2173 */ 2174 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2175 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2176 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2177 2178 String msg; 2179 if (deletedPkg == null) { 2180 msg = "Updated system package " + deletedAppName 2181 + " no longer exists; wiping its data"; 2182 removeDataDirsLI(null, deletedAppName); 2183 } else { 2184 msg = "Updated system app + " + deletedAppName 2185 + " no longer present; removing system privileges for " 2186 + deletedAppName; 2187 2188 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2189 2190 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2191 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2192 } 2193 logCriticalInfo(Log.WARN, msg); 2194 } 2195 2196 /** 2197 * Make sure all system apps that we expected to appear on 2198 * the userdata partition actually showed up. If they never 2199 * appeared, crawl back and revive the system version. 2200 */ 2201 for (int i = 0; i < mExpectingBetter.size(); i++) { 2202 final String packageName = mExpectingBetter.keyAt(i); 2203 if (!mPackages.containsKey(packageName)) { 2204 final File scanFile = mExpectingBetter.valueAt(i); 2205 2206 logCriticalInfo(Log.WARN, "Expected better " + packageName 2207 + " but never showed up; reverting to system"); 2208 2209 final int reparseFlags; 2210 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2211 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2212 | PackageParser.PARSE_IS_SYSTEM_DIR 2213 | PackageParser.PARSE_IS_PRIVILEGED; 2214 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2215 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2216 | PackageParser.PARSE_IS_SYSTEM_DIR; 2217 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2218 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2219 | PackageParser.PARSE_IS_SYSTEM_DIR; 2220 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2221 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2222 | PackageParser.PARSE_IS_SYSTEM_DIR; 2223 } else { 2224 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2225 continue; 2226 } 2227 2228 mSettings.enableSystemPackageLPw(packageName); 2229 2230 try { 2231 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2232 } catch (PackageManagerException e) { 2233 Slog.e(TAG, "Failed to parse original system package: " 2234 + e.getMessage()); 2235 } 2236 } 2237 } 2238 } 2239 mExpectingBetter.clear(); 2240 2241 // Now that we know all of the shared libraries, update all clients to have 2242 // the correct library paths. 2243 updateAllSharedLibrariesLPw(); 2244 2245 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2246 // NOTE: We ignore potential failures here during a system scan (like 2247 // the rest of the commands above) because there's precious little we 2248 // can do about it. A settings error is reported, though. 2249 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2250 false /* force dexopt */, false /* defer dexopt */); 2251 } 2252 2253 // Now that we know all the packages we are keeping, 2254 // read and update their last usage times. 2255 mPackageUsage.readLP(); 2256 2257 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2258 SystemClock.uptimeMillis()); 2259 Slog.i(TAG, "Time to scan packages: " 2260 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2261 + " seconds"); 2262 2263 // If the platform SDK has changed since the last time we booted, 2264 // we need to re-grant app permission to catch any new ones that 2265 // appear. This is really a hack, and means that apps can in some 2266 // cases get permissions that the user didn't initially explicitly 2267 // allow... it would be nice to have some better way to handle 2268 // this situation. 2269 final VersionInfo ver = mSettings.getInternalVersion(); 2270 2271 int updateFlags = UPDATE_PERMISSIONS_ALL; 2272 if (ver.sdkVersion != mSdkVersion) { 2273 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2274 + mSdkVersion + "; regranting permissions for internal storage"); 2275 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2276 } 2277 updatePermissionsLPw(null, null, updateFlags); 2278 ver.sdkVersion = mSdkVersion; 2279 2280 // If this is the first boot, and it is a normal boot, then 2281 // we need to initialize the default preferred apps. 2282 if (!mRestoredSettings && !onlyCore) { 2283 mSettings.applyDefaultPreferredAppsLPw(this, UserHandle.USER_OWNER); 2284 applyFactoryDefaultBrowserLPw(UserHandle.USER_OWNER); 2285 primeDomainVerificationsLPw(UserHandle.USER_OWNER); 2286 } 2287 2288 // If this is first boot after an OTA, and a normal boot, then 2289 // we need to clear code cache directories. 2290 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2291 if (mIsUpgrade && !onlyCore) { 2292 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2293 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2294 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2295 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2296 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2297 } 2298 } 2299 ver.fingerprint = Build.FINGERPRINT; 2300 } 2301 2302 checkDefaultBrowser(); 2303 2304 // All the changes are done during package scanning. 2305 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2306 2307 // can downgrade to reader 2308 mSettings.writeLPr(); 2309 2310 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2311 SystemClock.uptimeMillis()); 2312 2313 mRequiredVerifierPackage = getRequiredVerifierLPr(); 2314 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2315 2316 mInstallerService = new PackageInstallerService(context, this); 2317 2318 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2319 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2320 mIntentFilterVerifierComponent); 2321 2322 } // synchronized (mPackages) 2323 } // synchronized (mInstallLock) 2324 2325 // Now after opening every single application zip, make sure they 2326 // are all flushed. Not really needed, but keeps things nice and 2327 // tidy. 2328 Runtime.getRuntime().gc(); 2329 2330 // Expose private service for system components to use. 2331 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2332 } 2333 2334 @Override 2335 public boolean isFirstBoot() { 2336 return !mRestoredSettings; 2337 } 2338 2339 @Override 2340 public boolean isOnlyCoreApps() { 2341 return mOnlyCore; 2342 } 2343 2344 @Override 2345 public boolean isUpgrade() { 2346 return mIsUpgrade; 2347 } 2348 2349 private String getRequiredVerifierLPr() { 2350 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2351 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2352 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 2353 2354 String requiredVerifier = null; 2355 2356 final int N = receivers.size(); 2357 for (int i = 0; i < N; i++) { 2358 final ResolveInfo info = receivers.get(i); 2359 2360 if (info.activityInfo == null) { 2361 continue; 2362 } 2363 2364 final String packageName = info.activityInfo.packageName; 2365 2366 if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 2367 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2368 continue; 2369 } 2370 2371 if (requiredVerifier != null) { 2372 throw new RuntimeException("There can be only one required verifier"); 2373 } 2374 2375 requiredVerifier = packageName; 2376 } 2377 2378 return requiredVerifier; 2379 } 2380 2381 private String getRequiredInstallerLPr() { 2382 Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2383 installerIntent.addCategory(Intent.CATEGORY_DEFAULT); 2384 installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2385 2386 final List<ResolveInfo> installers = queryIntentActivities(installerIntent, 2387 PACKAGE_MIME_TYPE, 0, 0); 2388 2389 String requiredInstaller = null; 2390 2391 final int N = installers.size(); 2392 for (int i = 0; i < N; i++) { 2393 final ResolveInfo info = installers.get(i); 2394 final String packageName = info.activityInfo.packageName; 2395 2396 if (!info.activityInfo.applicationInfo.isSystemApp()) { 2397 continue; 2398 } 2399 2400 if (requiredInstaller != null) { 2401 throw new RuntimeException("There must be one required installer"); 2402 } 2403 2404 requiredInstaller = packageName; 2405 } 2406 2407 if (requiredInstaller == null) { 2408 throw new RuntimeException("There must be one required installer"); 2409 } 2410 2411 return requiredInstaller; 2412 } 2413 2414 private ComponentName getIntentFilterVerifierComponentNameLPr() { 2415 final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2416 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2417 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */); 2418 2419 ComponentName verifierComponentName = null; 2420 2421 int priority = -1000; 2422 final int N = receivers.size(); 2423 for (int i = 0; i < N; i++) { 2424 final ResolveInfo info = receivers.get(i); 2425 2426 if (info.activityInfo == null) { 2427 continue; 2428 } 2429 2430 final String packageName = info.activityInfo.packageName; 2431 2432 final PackageSetting ps = mSettings.mPackages.get(packageName); 2433 if (ps == null) { 2434 continue; 2435 } 2436 2437 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2438 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2439 continue; 2440 } 2441 2442 // Select the IntentFilterVerifier with the highest priority 2443 if (priority < info.priority) { 2444 priority = info.priority; 2445 verifierComponentName = new ComponentName(packageName, info.activityInfo.name); 2446 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Selecting IntentFilterVerifier: " 2447 + verifierComponentName + " with priority: " + info.priority); 2448 } 2449 } 2450 2451 return verifierComponentName; 2452 } 2453 2454 private void primeDomainVerificationsLPw(int userId) { 2455 if (DEBUG_DOMAIN_VERIFICATION) { 2456 Slog.d(TAG, "Priming domain verifications in user " + userId); 2457 } 2458 2459 SystemConfig systemConfig = SystemConfig.getInstance(); 2460 ArraySet<String> packages = systemConfig.getLinkedApps(); 2461 ArraySet<String> domains = new ArraySet<String>(); 2462 2463 for (String packageName : packages) { 2464 PackageParser.Package pkg = mPackages.get(packageName); 2465 if (pkg != null) { 2466 if (!pkg.isSystemApp()) { 2467 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2468 continue; 2469 } 2470 2471 domains.clear(); 2472 for (PackageParser.Activity a : pkg.activities) { 2473 for (ActivityIntentInfo filter : a.intents) { 2474 if (hasValidDomains(filter)) { 2475 domains.addAll(filter.getHostsList()); 2476 } 2477 } 2478 } 2479 2480 if (domains.size() > 0) { 2481 if (DEBUG_DOMAIN_VERIFICATION) { 2482 Slog.v(TAG, " + " + packageName); 2483 } 2484 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2485 // state w.r.t. the formal app-linkage "no verification attempted" state; 2486 // and then 'always' in the per-user state actually used for intent resolution. 2487 final IntentFilterVerificationInfo ivi; 2488 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2489 new ArrayList<String>(domains)); 2490 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2491 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2492 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2493 } else { 2494 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2495 + "' does not handle web links"); 2496 } 2497 } else { 2498 Slog.w(TAG, "Unknown package '" + packageName + "' in sysconfig <app-link>"); 2499 } 2500 } 2501 2502 scheduleWritePackageRestrictionsLocked(userId); 2503 scheduleWriteSettingsLocked(); 2504 } 2505 2506 private void applyFactoryDefaultBrowserLPw(int userId) { 2507 // The default browser app's package name is stored in a string resource, 2508 // with a product-specific overlay used for vendor customization. 2509 String browserPkg = mContext.getResources().getString( 2510 com.android.internal.R.string.default_browser); 2511 if (!TextUtils.isEmpty(browserPkg)) { 2512 // non-empty string => required to be a known package 2513 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2514 if (ps == null) { 2515 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2516 browserPkg = null; 2517 } else { 2518 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2519 } 2520 } 2521 2522 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2523 // default. If there's more than one, just leave everything alone. 2524 if (browserPkg == null) { 2525 calculateDefaultBrowserLPw(userId); 2526 } 2527 } 2528 2529 private void calculateDefaultBrowserLPw(int userId) { 2530 List<String> allBrowsers = resolveAllBrowserApps(userId); 2531 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2532 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2533 } 2534 2535 private List<String> resolveAllBrowserApps(int userId) { 2536 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2537 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2538 PackageManager.MATCH_ALL, userId); 2539 2540 final int count = list.size(); 2541 List<String> result = new ArrayList<String>(count); 2542 for (int i=0; i<count; i++) { 2543 ResolveInfo info = list.get(i); 2544 if (info.activityInfo == null 2545 || !info.handleAllWebDataURI 2546 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2547 || result.contains(info.activityInfo.packageName)) { 2548 continue; 2549 } 2550 result.add(info.activityInfo.packageName); 2551 } 2552 2553 return result; 2554 } 2555 2556 private boolean packageIsBrowser(String packageName, int userId) { 2557 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2558 PackageManager.MATCH_ALL, userId); 2559 final int N = list.size(); 2560 for (int i = 0; i < N; i++) { 2561 ResolveInfo info = list.get(i); 2562 if (packageName.equals(info.activityInfo.packageName)) { 2563 return true; 2564 } 2565 } 2566 return false; 2567 } 2568 2569 private void checkDefaultBrowser() { 2570 final int myUserId = UserHandle.myUserId(); 2571 final String packageName = getDefaultBrowserPackageName(myUserId); 2572 if (packageName != null) { 2573 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2574 if (info == null) { 2575 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2576 synchronized (mPackages) { 2577 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2578 } 2579 } 2580 } 2581 } 2582 2583 @Override 2584 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2585 throws RemoteException { 2586 try { 2587 return super.onTransact(code, data, reply, flags); 2588 } catch (RuntimeException e) { 2589 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2590 Slog.wtf(TAG, "Package Manager Crash", e); 2591 } 2592 throw e; 2593 } 2594 } 2595 2596 void cleanupInstallFailedPackage(PackageSetting ps) { 2597 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2598 2599 removeDataDirsLI(ps.volumeUuid, ps.name); 2600 if (ps.codePath != null) { 2601 if (ps.codePath.isDirectory()) { 2602 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath()); 2603 } else { 2604 ps.codePath.delete(); 2605 } 2606 } 2607 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2608 if (ps.resourcePath.isDirectory()) { 2609 FileUtils.deleteContents(ps.resourcePath); 2610 } 2611 ps.resourcePath.delete(); 2612 } 2613 mSettings.removePackageLPw(ps.name); 2614 } 2615 2616 static int[] appendInts(int[] cur, int[] add) { 2617 if (add == null) return cur; 2618 if (cur == null) return add; 2619 final int N = add.length; 2620 for (int i=0; i<N; i++) { 2621 cur = appendInt(cur, add[i]); 2622 } 2623 return cur; 2624 } 2625 2626 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2627 if (!sUserManager.exists(userId)) return null; 2628 final PackageSetting ps = (PackageSetting) p.mExtras; 2629 if (ps == null) { 2630 return null; 2631 } 2632 2633 final PermissionsState permissionsState = ps.getPermissionsState(); 2634 2635 final int[] gids = permissionsState.computeGids(userId); 2636 final Set<String> permissions = permissionsState.getPermissions(userId); 2637 final PackageUserState state = ps.readUserState(userId); 2638 2639 return PackageParser.generatePackageInfo(p, gids, flags, 2640 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2641 } 2642 2643 @Override 2644 public boolean isPackageFrozen(String packageName) { 2645 synchronized (mPackages) { 2646 final PackageSetting ps = mSettings.mPackages.get(packageName); 2647 if (ps != null) { 2648 return ps.frozen; 2649 } 2650 } 2651 Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen"); 2652 return true; 2653 } 2654 2655 @Override 2656 public boolean isPackageAvailable(String packageName, int userId) { 2657 if (!sUserManager.exists(userId)) return false; 2658 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 2659 synchronized (mPackages) { 2660 PackageParser.Package p = mPackages.get(packageName); 2661 if (p != null) { 2662 final PackageSetting ps = (PackageSetting) p.mExtras; 2663 if (ps != null) { 2664 final PackageUserState state = ps.readUserState(userId); 2665 if (state != null) { 2666 return PackageParser.isAvailable(state); 2667 } 2668 } 2669 } 2670 } 2671 return false; 2672 } 2673 2674 @Override 2675 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2676 if (!sUserManager.exists(userId)) return null; 2677 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 2678 // reader 2679 synchronized (mPackages) { 2680 PackageParser.Package p = mPackages.get(packageName); 2681 if (DEBUG_PACKAGE_INFO) 2682 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2683 if (p != null) { 2684 return generatePackageInfo(p, flags, userId); 2685 } 2686 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2687 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2688 } 2689 } 2690 return null; 2691 } 2692 2693 @Override 2694 public String[] currentToCanonicalPackageNames(String[] names) { 2695 String[] out = new String[names.length]; 2696 // reader 2697 synchronized (mPackages) { 2698 for (int i=names.length-1; i>=0; i--) { 2699 PackageSetting ps = mSettings.mPackages.get(names[i]); 2700 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2701 } 2702 } 2703 return out; 2704 } 2705 2706 @Override 2707 public String[] canonicalToCurrentPackageNames(String[] names) { 2708 String[] out = new String[names.length]; 2709 // reader 2710 synchronized (mPackages) { 2711 for (int i=names.length-1; i>=0; i--) { 2712 String cur = mSettings.mRenamedPackages.get(names[i]); 2713 out[i] = cur != null ? cur : names[i]; 2714 } 2715 } 2716 return out; 2717 } 2718 2719 @Override 2720 public int getPackageUid(String packageName, int userId) { 2721 if (!sUserManager.exists(userId)) return -1; 2722 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 2723 2724 // reader 2725 synchronized (mPackages) { 2726 PackageParser.Package p = mPackages.get(packageName); 2727 if(p != null) { 2728 return UserHandle.getUid(userId, p.applicationInfo.uid); 2729 } 2730 PackageSetting ps = mSettings.mPackages.get(packageName); 2731 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 2732 return -1; 2733 } 2734 p = ps.pkg; 2735 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 2736 } 2737 } 2738 2739 @Override 2740 public int[] getPackageGids(String packageName, int userId) throws RemoteException { 2741 if (!sUserManager.exists(userId)) { 2742 return null; 2743 } 2744 2745 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 2746 "getPackageGids"); 2747 2748 // reader 2749 synchronized (mPackages) { 2750 PackageParser.Package p = mPackages.get(packageName); 2751 if (DEBUG_PACKAGE_INFO) { 2752 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 2753 } 2754 if (p != null) { 2755 PackageSetting ps = (PackageSetting) p.mExtras; 2756 return ps.getPermissionsState().computeGids(userId); 2757 } 2758 } 2759 2760 return null; 2761 } 2762 2763 static PermissionInfo generatePermissionInfo( 2764 BasePermission bp, int flags) { 2765 if (bp.perm != null) { 2766 return PackageParser.generatePermissionInfo(bp.perm, flags); 2767 } 2768 PermissionInfo pi = new PermissionInfo(); 2769 pi.name = bp.name; 2770 pi.packageName = bp.sourcePackage; 2771 pi.nonLocalizedLabel = bp.name; 2772 pi.protectionLevel = bp.protectionLevel; 2773 return pi; 2774 } 2775 2776 @Override 2777 public PermissionInfo getPermissionInfo(String name, int flags) { 2778 // reader 2779 synchronized (mPackages) { 2780 final BasePermission p = mSettings.mPermissions.get(name); 2781 if (p != null) { 2782 return generatePermissionInfo(p, flags); 2783 } 2784 return null; 2785 } 2786 } 2787 2788 @Override 2789 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2790 // reader 2791 synchronized (mPackages) { 2792 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2793 for (BasePermission p : mSettings.mPermissions.values()) { 2794 if (group == null) { 2795 if (p.perm == null || p.perm.info.group == null) { 2796 out.add(generatePermissionInfo(p, flags)); 2797 } 2798 } else { 2799 if (p.perm != null && group.equals(p.perm.info.group)) { 2800 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2801 } 2802 } 2803 } 2804 2805 if (out.size() > 0) { 2806 return out; 2807 } 2808 return mPermissionGroups.containsKey(group) ? out : null; 2809 } 2810 } 2811 2812 @Override 2813 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2814 // reader 2815 synchronized (mPackages) { 2816 return PackageParser.generatePermissionGroupInfo( 2817 mPermissionGroups.get(name), flags); 2818 } 2819 } 2820 2821 @Override 2822 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2823 // reader 2824 synchronized (mPackages) { 2825 final int N = mPermissionGroups.size(); 2826 ArrayList<PermissionGroupInfo> out 2827 = new ArrayList<PermissionGroupInfo>(N); 2828 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2829 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2830 } 2831 return out; 2832 } 2833 } 2834 2835 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2836 int userId) { 2837 if (!sUserManager.exists(userId)) return null; 2838 PackageSetting ps = mSettings.mPackages.get(packageName); 2839 if (ps != null) { 2840 if (ps.pkg == null) { 2841 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2842 flags, userId); 2843 if (pInfo != null) { 2844 return pInfo.applicationInfo; 2845 } 2846 return null; 2847 } 2848 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2849 ps.readUserState(userId), userId); 2850 } 2851 return null; 2852 } 2853 2854 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2855 int userId) { 2856 if (!sUserManager.exists(userId)) return null; 2857 PackageSetting ps = mSettings.mPackages.get(packageName); 2858 if (ps != null) { 2859 PackageParser.Package pkg = ps.pkg; 2860 if (pkg == null) { 2861 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2862 return null; 2863 } 2864 // Only data remains, so we aren't worried about code paths 2865 pkg = new PackageParser.Package(packageName); 2866 pkg.applicationInfo.packageName = packageName; 2867 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2868 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 2869 pkg.applicationInfo.dataDir = Environment 2870 .getDataUserPackageDirectory(ps.volumeUuid, userId, packageName) 2871 .getAbsolutePath(); 2872 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2873 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2874 } 2875 return generatePackageInfo(pkg, flags, userId); 2876 } 2877 return null; 2878 } 2879 2880 @Override 2881 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2882 if (!sUserManager.exists(userId)) return null; 2883 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2884 // writer 2885 synchronized (mPackages) { 2886 PackageParser.Package p = mPackages.get(packageName); 2887 if (DEBUG_PACKAGE_INFO) Log.v( 2888 TAG, "getApplicationInfo " + packageName 2889 + ": " + p); 2890 if (p != null) { 2891 PackageSetting ps = mSettings.mPackages.get(packageName); 2892 if (ps == null) return null; 2893 // Note: isEnabledLP() does not apply here - always return info 2894 return PackageParser.generateApplicationInfo( 2895 p, flags, ps.readUserState(userId), userId); 2896 } 2897 if ("android".equals(packageName)||"system".equals(packageName)) { 2898 return mAndroidApplication; 2899 } 2900 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2901 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2902 } 2903 } 2904 return null; 2905 } 2906 2907 @Override 2908 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 2909 final IPackageDataObserver observer) { 2910 mContext.enforceCallingOrSelfPermission( 2911 android.Manifest.permission.CLEAR_APP_CACHE, null); 2912 // Queue up an async operation since clearing cache may take a little while. 2913 mHandler.post(new Runnable() { 2914 public void run() { 2915 mHandler.removeCallbacks(this); 2916 int retCode = -1; 2917 synchronized (mInstallLock) { 2918 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2919 if (retCode < 0) { 2920 Slog.w(TAG, "Couldn't clear application caches"); 2921 } 2922 } 2923 if (observer != null) { 2924 try { 2925 observer.onRemoveCompleted(null, (retCode >= 0)); 2926 } catch (RemoteException e) { 2927 Slog.w(TAG, "RemoveException when invoking call back"); 2928 } 2929 } 2930 } 2931 }); 2932 } 2933 2934 @Override 2935 public void freeStorage(final String volumeUuid, final long freeStorageSize, 2936 final IntentSender pi) { 2937 mContext.enforceCallingOrSelfPermission( 2938 android.Manifest.permission.CLEAR_APP_CACHE, null); 2939 // Queue up an async operation since clearing cache may take a little while. 2940 mHandler.post(new Runnable() { 2941 public void run() { 2942 mHandler.removeCallbacks(this); 2943 int retCode = -1; 2944 synchronized (mInstallLock) { 2945 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2946 if (retCode < 0) { 2947 Slog.w(TAG, "Couldn't clear application caches"); 2948 } 2949 } 2950 if(pi != null) { 2951 try { 2952 // Callback via pending intent 2953 int code = (retCode >= 0) ? 1 : 0; 2954 pi.sendIntent(null, code, null, 2955 null, null); 2956 } catch (SendIntentException e1) { 2957 Slog.i(TAG, "Failed to send pending intent"); 2958 } 2959 } 2960 } 2961 }); 2962 } 2963 2964 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 2965 synchronized (mInstallLock) { 2966 if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) { 2967 throw new IOException("Failed to free enough space"); 2968 } 2969 } 2970 } 2971 2972 @Override 2973 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2974 if (!sUserManager.exists(userId)) return null; 2975 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 2976 synchronized (mPackages) { 2977 PackageParser.Activity a = mActivities.mActivities.get(component); 2978 2979 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2980 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2981 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2982 if (ps == null) return null; 2983 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2984 userId); 2985 } 2986 if (mResolveComponentName.equals(component)) { 2987 return PackageParser.generateActivityInfo(mResolveActivity, flags, 2988 new PackageUserState(), userId); 2989 } 2990 } 2991 return null; 2992 } 2993 2994 @Override 2995 public boolean activitySupportsIntent(ComponentName component, Intent intent, 2996 String resolvedType) { 2997 synchronized (mPackages) { 2998 if (component.equals(mResolveComponentName)) { 2999 // The resolver supports EVERYTHING! 3000 return true; 3001 } 3002 PackageParser.Activity a = mActivities.mActivities.get(component); 3003 if (a == null) { 3004 return false; 3005 } 3006 for (int i=0; i<a.intents.size(); i++) { 3007 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3008 intent.getData(), intent.getCategories(), TAG) >= 0) { 3009 return true; 3010 } 3011 } 3012 return false; 3013 } 3014 } 3015 3016 @Override 3017 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3018 if (!sUserManager.exists(userId)) return null; 3019 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 3020 synchronized (mPackages) { 3021 PackageParser.Activity a = mReceivers.mActivities.get(component); 3022 if (DEBUG_PACKAGE_INFO) Log.v( 3023 TAG, "getReceiverInfo " + component + ": " + a); 3024 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 3025 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3026 if (ps == null) return null; 3027 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3028 userId); 3029 } 3030 } 3031 return null; 3032 } 3033 3034 @Override 3035 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3036 if (!sUserManager.exists(userId)) return null; 3037 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 3038 synchronized (mPackages) { 3039 PackageParser.Service s = mServices.mServices.get(component); 3040 if (DEBUG_PACKAGE_INFO) Log.v( 3041 TAG, "getServiceInfo " + component + ": " + s); 3042 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 3043 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3044 if (ps == null) return null; 3045 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3046 userId); 3047 } 3048 } 3049 return null; 3050 } 3051 3052 @Override 3053 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3054 if (!sUserManager.exists(userId)) return null; 3055 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 3056 synchronized (mPackages) { 3057 PackageParser.Provider p = mProviders.mProviders.get(component); 3058 if (DEBUG_PACKAGE_INFO) Log.v( 3059 TAG, "getProviderInfo " + component + ": " + p); 3060 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 3061 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3062 if (ps == null) return null; 3063 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3064 userId); 3065 } 3066 } 3067 return null; 3068 } 3069 3070 @Override 3071 public String[] getSystemSharedLibraryNames() { 3072 Set<String> libSet; 3073 synchronized (mPackages) { 3074 libSet = mSharedLibraries.keySet(); 3075 int size = libSet.size(); 3076 if (size > 0) { 3077 String[] libs = new String[size]; 3078 libSet.toArray(libs); 3079 return libs; 3080 } 3081 } 3082 return null; 3083 } 3084 3085 /** 3086 * @hide 3087 */ 3088 PackageParser.Package findSharedNonSystemLibrary(String libName) { 3089 synchronized (mPackages) { 3090 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 3091 if (lib != null && lib.apk != null) { 3092 return mPackages.get(lib.apk); 3093 } 3094 } 3095 return null; 3096 } 3097 3098 @Override 3099 public FeatureInfo[] getSystemAvailableFeatures() { 3100 Collection<FeatureInfo> featSet; 3101 synchronized (mPackages) { 3102 featSet = mAvailableFeatures.values(); 3103 int size = featSet.size(); 3104 if (size > 0) { 3105 FeatureInfo[] features = new FeatureInfo[size+1]; 3106 featSet.toArray(features); 3107 FeatureInfo fi = new FeatureInfo(); 3108 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3109 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3110 features[size] = fi; 3111 return features; 3112 } 3113 } 3114 return null; 3115 } 3116 3117 @Override 3118 public boolean hasSystemFeature(String name) { 3119 synchronized (mPackages) { 3120 return mAvailableFeatures.containsKey(name); 3121 } 3122 } 3123 3124 private void checkValidCaller(int uid, int userId) { 3125 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 3126 return; 3127 3128 throw new SecurityException("Caller uid=" + uid 3129 + " is not privileged to communicate with user=" + userId); 3130 } 3131 3132 @Override 3133 public int checkPermission(String permName, String pkgName, int userId) { 3134 if (!sUserManager.exists(userId)) { 3135 return PackageManager.PERMISSION_DENIED; 3136 } 3137 3138 synchronized (mPackages) { 3139 final PackageParser.Package p = mPackages.get(pkgName); 3140 if (p != null && p.mExtras != null) { 3141 final PackageSetting ps = (PackageSetting) p.mExtras; 3142 final PermissionsState permissionsState = ps.getPermissionsState(); 3143 if (permissionsState.hasPermission(permName, userId)) { 3144 return PackageManager.PERMISSION_GRANTED; 3145 } 3146 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3147 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3148 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3149 return PackageManager.PERMISSION_GRANTED; 3150 } 3151 } 3152 } 3153 3154 return PackageManager.PERMISSION_DENIED; 3155 } 3156 3157 @Override 3158 public int checkUidPermission(String permName, int uid) { 3159 final int userId = UserHandle.getUserId(uid); 3160 3161 if (!sUserManager.exists(userId)) { 3162 return PackageManager.PERMISSION_DENIED; 3163 } 3164 3165 synchronized (mPackages) { 3166 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3167 if (obj != null) { 3168 final SettingBase ps = (SettingBase) obj; 3169 final PermissionsState permissionsState = ps.getPermissionsState(); 3170 if (permissionsState.hasPermission(permName, userId)) { 3171 return PackageManager.PERMISSION_GRANTED; 3172 } 3173 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3174 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3175 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3176 return PackageManager.PERMISSION_GRANTED; 3177 } 3178 } else { 3179 ArraySet<String> perms = mSystemPermissions.get(uid); 3180 if (perms != null) { 3181 if (perms.contains(permName)) { 3182 return PackageManager.PERMISSION_GRANTED; 3183 } 3184 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3185 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3186 return PackageManager.PERMISSION_GRANTED; 3187 } 3188 } 3189 } 3190 } 3191 3192 return PackageManager.PERMISSION_DENIED; 3193 } 3194 3195 @Override 3196 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3197 if (UserHandle.getCallingUserId() != userId) { 3198 mContext.enforceCallingPermission( 3199 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3200 "isPermissionRevokedByPolicy for user " + userId); 3201 } 3202 3203 if (checkPermission(permission, packageName, userId) 3204 == PackageManager.PERMISSION_GRANTED) { 3205 return false; 3206 } 3207 3208 final long identity = Binder.clearCallingIdentity(); 3209 try { 3210 final int flags = getPermissionFlags(permission, packageName, userId); 3211 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3212 } finally { 3213 Binder.restoreCallingIdentity(identity); 3214 } 3215 } 3216 3217 @Override 3218 public String getPermissionControllerPackageName() { 3219 synchronized (mPackages) { 3220 return mRequiredInstallerPackage; 3221 } 3222 } 3223 3224 /** 3225 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3226 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3227 * @param checkShell TODO(yamasani): 3228 * @param message the message to log on security exception 3229 */ 3230 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3231 boolean checkShell, String message) { 3232 if (userId < 0) { 3233 throw new IllegalArgumentException("Invalid userId " + userId); 3234 } 3235 if (checkShell) { 3236 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3237 } 3238 if (userId == UserHandle.getUserId(callingUid)) return; 3239 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3240 if (requireFullPermission) { 3241 mContext.enforceCallingOrSelfPermission( 3242 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3243 } else { 3244 try { 3245 mContext.enforceCallingOrSelfPermission( 3246 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3247 } catch (SecurityException se) { 3248 mContext.enforceCallingOrSelfPermission( 3249 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3250 } 3251 } 3252 } 3253 } 3254 3255 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3256 if (callingUid == Process.SHELL_UID) { 3257 if (userHandle >= 0 3258 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3259 throw new SecurityException("Shell does not have permission to access user " 3260 + userHandle); 3261 } else if (userHandle < 0) { 3262 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3263 + Debug.getCallers(3)); 3264 } 3265 } 3266 } 3267 3268 private BasePermission findPermissionTreeLP(String permName) { 3269 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3270 if (permName.startsWith(bp.name) && 3271 permName.length() > bp.name.length() && 3272 permName.charAt(bp.name.length()) == '.') { 3273 return bp; 3274 } 3275 } 3276 return null; 3277 } 3278 3279 private BasePermission checkPermissionTreeLP(String permName) { 3280 if (permName != null) { 3281 BasePermission bp = findPermissionTreeLP(permName); 3282 if (bp != null) { 3283 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3284 return bp; 3285 } 3286 throw new SecurityException("Calling uid " 3287 + Binder.getCallingUid() 3288 + " is not allowed to add to permission tree " 3289 + bp.name + " owned by uid " + bp.uid); 3290 } 3291 } 3292 throw new SecurityException("No permission tree found for " + permName); 3293 } 3294 3295 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3296 if (s1 == null) { 3297 return s2 == null; 3298 } 3299 if (s2 == null) { 3300 return false; 3301 } 3302 if (s1.getClass() != s2.getClass()) { 3303 return false; 3304 } 3305 return s1.equals(s2); 3306 } 3307 3308 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3309 if (pi1.icon != pi2.icon) return false; 3310 if (pi1.logo != pi2.logo) return false; 3311 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3312 if (!compareStrings(pi1.name, pi2.name)) return false; 3313 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3314 // We'll take care of setting this one. 3315 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3316 // These are not currently stored in settings. 3317 //if (!compareStrings(pi1.group, pi2.group)) return false; 3318 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3319 //if (pi1.labelRes != pi2.labelRes) return false; 3320 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3321 return true; 3322 } 3323 3324 int permissionInfoFootprint(PermissionInfo info) { 3325 int size = info.name.length(); 3326 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3327 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3328 return size; 3329 } 3330 3331 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3332 int size = 0; 3333 for (BasePermission perm : mSettings.mPermissions.values()) { 3334 if (perm.uid == tree.uid) { 3335 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3336 } 3337 } 3338 return size; 3339 } 3340 3341 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3342 // We calculate the max size of permissions defined by this uid and throw 3343 // if that plus the size of 'info' would exceed our stated maximum. 3344 if (tree.uid != Process.SYSTEM_UID) { 3345 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3346 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3347 throw new SecurityException("Permission tree size cap exceeded"); 3348 } 3349 } 3350 } 3351 3352 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3353 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3354 throw new SecurityException("Label must be specified in permission"); 3355 } 3356 BasePermission tree = checkPermissionTreeLP(info.name); 3357 BasePermission bp = mSettings.mPermissions.get(info.name); 3358 boolean added = bp == null; 3359 boolean changed = true; 3360 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3361 if (added) { 3362 enforcePermissionCapLocked(info, tree); 3363 bp = new BasePermission(info.name, tree.sourcePackage, 3364 BasePermission.TYPE_DYNAMIC); 3365 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3366 throw new SecurityException( 3367 "Not allowed to modify non-dynamic permission " 3368 + info.name); 3369 } else { 3370 if (bp.protectionLevel == fixedLevel 3371 && bp.perm.owner.equals(tree.perm.owner) 3372 && bp.uid == tree.uid 3373 && comparePermissionInfos(bp.perm.info, info)) { 3374 changed = false; 3375 } 3376 } 3377 bp.protectionLevel = fixedLevel; 3378 info = new PermissionInfo(info); 3379 info.protectionLevel = fixedLevel; 3380 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3381 bp.perm.info.packageName = tree.perm.info.packageName; 3382 bp.uid = tree.uid; 3383 if (added) { 3384 mSettings.mPermissions.put(info.name, bp); 3385 } 3386 if (changed) { 3387 if (!async) { 3388 mSettings.writeLPr(); 3389 } else { 3390 scheduleWriteSettingsLocked(); 3391 } 3392 } 3393 return added; 3394 } 3395 3396 @Override 3397 public boolean addPermission(PermissionInfo info) { 3398 synchronized (mPackages) { 3399 return addPermissionLocked(info, false); 3400 } 3401 } 3402 3403 @Override 3404 public boolean addPermissionAsync(PermissionInfo info) { 3405 synchronized (mPackages) { 3406 return addPermissionLocked(info, true); 3407 } 3408 } 3409 3410 @Override 3411 public void removePermission(String name) { 3412 synchronized (mPackages) { 3413 checkPermissionTreeLP(name); 3414 BasePermission bp = mSettings.mPermissions.get(name); 3415 if (bp != null) { 3416 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3417 throw new SecurityException( 3418 "Not allowed to modify non-dynamic permission " 3419 + name); 3420 } 3421 mSettings.mPermissions.remove(name); 3422 mSettings.writeLPr(); 3423 } 3424 } 3425 } 3426 3427 private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg, 3428 BasePermission bp) { 3429 int index = pkg.requestedPermissions.indexOf(bp.name); 3430 if (index == -1) { 3431 throw new SecurityException("Package " + pkg.packageName 3432 + " has not requested permission " + bp.name); 3433 } 3434 if (!bp.isRuntime()) { 3435 throw new SecurityException("Permission " + bp.name 3436 + " is not a changeable permission type"); 3437 } 3438 } 3439 3440 @Override 3441 public void grantRuntimePermission(String packageName, String name, final int userId) { 3442 if (!sUserManager.exists(userId)) { 3443 Log.e(TAG, "No such user:" + userId); 3444 return; 3445 } 3446 3447 mContext.enforceCallingOrSelfPermission( 3448 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3449 "grantRuntimePermission"); 3450 3451 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3452 "grantRuntimePermission"); 3453 3454 final int uid; 3455 final SettingBase sb; 3456 3457 synchronized (mPackages) { 3458 final PackageParser.Package pkg = mPackages.get(packageName); 3459 if (pkg == null) { 3460 throw new IllegalArgumentException("Unknown package: " + packageName); 3461 } 3462 3463 final BasePermission bp = mSettings.mPermissions.get(name); 3464 if (bp == null) { 3465 throw new IllegalArgumentException("Unknown permission: " + name); 3466 } 3467 3468 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3469 3470 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3471 sb = (SettingBase) pkg.mExtras; 3472 if (sb == null) { 3473 throw new IllegalArgumentException("Unknown package: " + packageName); 3474 } 3475 3476 final PermissionsState permissionsState = sb.getPermissionsState(); 3477 3478 final int flags = permissionsState.getPermissionFlags(name, userId); 3479 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3480 throw new SecurityException("Cannot grant system fixed permission: " 3481 + name + " for package: " + packageName); 3482 } 3483 3484 final int result = permissionsState.grantRuntimePermission(bp, userId); 3485 switch (result) { 3486 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3487 return; 3488 } 3489 3490 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3491 mHandler.post(new Runnable() { 3492 @Override 3493 public void run() { 3494 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED); 3495 } 3496 }); 3497 } break; 3498 } 3499 3500 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3501 3502 // Not critical if that is lost - app has to request again. 3503 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3504 } 3505 3506 // Only need to do this if user is initialized. Otherwise it's a new user 3507 // and there are no processes running as the user yet and there's no need 3508 // to make an expensive call to remount processes for the changed permissions. 3509 if (READ_EXTERNAL_STORAGE.equals(name) 3510 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3511 final long token = Binder.clearCallingIdentity(); 3512 try { 3513 if (sUserManager.isInitialized(userId)) { 3514 MountServiceInternal mountServiceInternal = LocalServices.getService( 3515 MountServiceInternal.class); 3516 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3517 } 3518 } finally { 3519 Binder.restoreCallingIdentity(token); 3520 } 3521 } 3522 } 3523 3524 @Override 3525 public void revokeRuntimePermission(String packageName, String name, int userId) { 3526 if (!sUserManager.exists(userId)) { 3527 Log.e(TAG, "No such user:" + userId); 3528 return; 3529 } 3530 3531 mContext.enforceCallingOrSelfPermission( 3532 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3533 "revokeRuntimePermission"); 3534 3535 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3536 "revokeRuntimePermission"); 3537 3538 final SettingBase sb; 3539 3540 synchronized (mPackages) { 3541 final PackageParser.Package pkg = mPackages.get(packageName); 3542 if (pkg == null) { 3543 throw new IllegalArgumentException("Unknown package: " + packageName); 3544 } 3545 3546 final BasePermission bp = mSettings.mPermissions.get(name); 3547 if (bp == null) { 3548 throw new IllegalArgumentException("Unknown permission: " + name); 3549 } 3550 3551 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3552 3553 sb = (SettingBase) pkg.mExtras; 3554 if (sb == null) { 3555 throw new IllegalArgumentException("Unknown package: " + packageName); 3556 } 3557 3558 final PermissionsState permissionsState = sb.getPermissionsState(); 3559 3560 final int flags = permissionsState.getPermissionFlags(name, userId); 3561 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3562 throw new SecurityException("Cannot revoke system fixed permission: " 3563 + name + " for package: " + packageName); 3564 } 3565 3566 if (permissionsState.revokeRuntimePermission(bp, userId) == 3567 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3568 return; 3569 } 3570 3571 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 3572 3573 // Critical, after this call app should never have the permission. 3574 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3575 } 3576 3577 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 3578 } 3579 3580 @Override 3581 public void resetRuntimePermissions() { 3582 mContext.enforceCallingOrSelfPermission( 3583 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3584 "revokeRuntimePermission"); 3585 3586 int callingUid = Binder.getCallingUid(); 3587 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3588 mContext.enforceCallingOrSelfPermission( 3589 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3590 "resetRuntimePermissions"); 3591 } 3592 3593 synchronized (mPackages) { 3594 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 3595 for (int userId : UserManagerService.getInstance().getUserIds()) { 3596 final int packageCount = mPackages.size(); 3597 for (int i = 0; i < packageCount; i++) { 3598 PackageParser.Package pkg = mPackages.valueAt(i); 3599 if (!(pkg.mExtras instanceof PackageSetting)) { 3600 continue; 3601 } 3602 PackageSetting ps = (PackageSetting) pkg.mExtras; 3603 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 3604 } 3605 } 3606 } 3607 } 3608 3609 @Override 3610 public int getPermissionFlags(String name, String packageName, int userId) { 3611 if (!sUserManager.exists(userId)) { 3612 return 0; 3613 } 3614 3615 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 3616 3617 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3618 "getPermissionFlags"); 3619 3620 synchronized (mPackages) { 3621 final PackageParser.Package pkg = mPackages.get(packageName); 3622 if (pkg == null) { 3623 throw new IllegalArgumentException("Unknown package: " + packageName); 3624 } 3625 3626 final BasePermission bp = mSettings.mPermissions.get(name); 3627 if (bp == null) { 3628 throw new IllegalArgumentException("Unknown permission: " + name); 3629 } 3630 3631 SettingBase sb = (SettingBase) pkg.mExtras; 3632 if (sb == null) { 3633 throw new IllegalArgumentException("Unknown package: " + packageName); 3634 } 3635 3636 PermissionsState permissionsState = sb.getPermissionsState(); 3637 return permissionsState.getPermissionFlags(name, userId); 3638 } 3639 } 3640 3641 @Override 3642 public void updatePermissionFlags(String name, String packageName, int flagMask, 3643 int flagValues, int userId) { 3644 if (!sUserManager.exists(userId)) { 3645 return; 3646 } 3647 3648 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 3649 3650 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3651 "updatePermissionFlags"); 3652 3653 // Only the system can change these flags and nothing else. 3654 if (getCallingUid() != Process.SYSTEM_UID) { 3655 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3656 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3657 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 3658 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 3659 } 3660 3661 synchronized (mPackages) { 3662 final PackageParser.Package pkg = mPackages.get(packageName); 3663 if (pkg == null) { 3664 throw new IllegalArgumentException("Unknown package: " + packageName); 3665 } 3666 3667 final BasePermission bp = mSettings.mPermissions.get(name); 3668 if (bp == null) { 3669 throw new IllegalArgumentException("Unknown permission: " + name); 3670 } 3671 3672 SettingBase sb = (SettingBase) pkg.mExtras; 3673 if (sb == null) { 3674 throw new IllegalArgumentException("Unknown package: " + packageName); 3675 } 3676 3677 PermissionsState permissionsState = sb.getPermissionsState(); 3678 3679 // Only the package manager can change flags for system component permissions. 3680 final int flags = permissionsState.getPermissionFlags(bp.name, userId); 3681 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3682 return; 3683 } 3684 3685 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 3686 3687 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 3688 // Install and runtime permissions are stored in different places, 3689 // so figure out what permission changed and persist the change. 3690 if (permissionsState.getInstallPermissionState(name) != null) { 3691 scheduleWriteSettingsLocked(); 3692 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 3693 || hadState) { 3694 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3695 } 3696 } 3697 } 3698 } 3699 3700 /** 3701 * Update the permission flags for all packages and runtime permissions of a user in order 3702 * to allow device or profile owner to remove POLICY_FIXED. 3703 */ 3704 @Override 3705 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 3706 if (!sUserManager.exists(userId)) { 3707 return; 3708 } 3709 3710 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 3711 3712 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3713 "updatePermissionFlagsForAllApps"); 3714 3715 // Only the system can change system fixed flags. 3716 if (getCallingUid() != Process.SYSTEM_UID) { 3717 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3718 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3719 } 3720 3721 synchronized (mPackages) { 3722 boolean changed = false; 3723 final int packageCount = mPackages.size(); 3724 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 3725 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 3726 SettingBase sb = (SettingBase) pkg.mExtras; 3727 if (sb == null) { 3728 continue; 3729 } 3730 PermissionsState permissionsState = sb.getPermissionsState(); 3731 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 3732 userId, flagMask, flagValues); 3733 } 3734 if (changed) { 3735 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3736 } 3737 } 3738 } 3739 3740 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 3741 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 3742 != PackageManager.PERMISSION_GRANTED 3743 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 3744 != PackageManager.PERMISSION_GRANTED) { 3745 throw new SecurityException(message + " requires " 3746 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 3747 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 3748 } 3749 } 3750 3751 @Override 3752 public boolean shouldShowRequestPermissionRationale(String permissionName, 3753 String packageName, int userId) { 3754 if (UserHandle.getCallingUserId() != userId) { 3755 mContext.enforceCallingPermission( 3756 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3757 "canShowRequestPermissionRationale for user " + userId); 3758 } 3759 3760 final int uid = getPackageUid(packageName, userId); 3761 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 3762 return false; 3763 } 3764 3765 if (checkPermission(permissionName, packageName, userId) 3766 == PackageManager.PERMISSION_GRANTED) { 3767 return false; 3768 } 3769 3770 final int flags; 3771 3772 final long identity = Binder.clearCallingIdentity(); 3773 try { 3774 flags = getPermissionFlags(permissionName, 3775 packageName, userId); 3776 } finally { 3777 Binder.restoreCallingIdentity(identity); 3778 } 3779 3780 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 3781 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 3782 | PackageManager.FLAG_PERMISSION_USER_FIXED; 3783 3784 if ((flags & fixedFlags) != 0) { 3785 return false; 3786 } 3787 3788 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 3789 } 3790 3791 void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) { 3792 BasePermission bp = mSettings.mPermissions.get(permission); 3793 if (bp == null) { 3794 throw new SecurityException("Missing " + permission + " permission"); 3795 } 3796 3797 SettingBase sb = (SettingBase) pkg.mExtras; 3798 PermissionsState permissionsState = sb.getPermissionsState(); 3799 3800 if (permissionsState.grantInstallPermission(bp) != 3801 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3802 scheduleWriteSettingsLocked(); 3803 } 3804 } 3805 3806 @Override 3807 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3808 mContext.enforceCallingOrSelfPermission( 3809 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 3810 "addOnPermissionsChangeListener"); 3811 3812 synchronized (mPackages) { 3813 mOnPermissionChangeListeners.addListenerLocked(listener); 3814 } 3815 } 3816 3817 @Override 3818 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3819 synchronized (mPackages) { 3820 mOnPermissionChangeListeners.removeListenerLocked(listener); 3821 } 3822 } 3823 3824 @Override 3825 public boolean isProtectedBroadcast(String actionName) { 3826 synchronized (mPackages) { 3827 return mProtectedBroadcasts.contains(actionName); 3828 } 3829 } 3830 3831 @Override 3832 public int checkSignatures(String pkg1, String pkg2) { 3833 synchronized (mPackages) { 3834 final PackageParser.Package p1 = mPackages.get(pkg1); 3835 final PackageParser.Package p2 = mPackages.get(pkg2); 3836 if (p1 == null || p1.mExtras == null 3837 || p2 == null || p2.mExtras == null) { 3838 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3839 } 3840 return compareSignatures(p1.mSignatures, p2.mSignatures); 3841 } 3842 } 3843 3844 @Override 3845 public int checkUidSignatures(int uid1, int uid2) { 3846 // Map to base uids. 3847 uid1 = UserHandle.getAppId(uid1); 3848 uid2 = UserHandle.getAppId(uid2); 3849 // reader 3850 synchronized (mPackages) { 3851 Signature[] s1; 3852 Signature[] s2; 3853 Object obj = mSettings.getUserIdLPr(uid1); 3854 if (obj != null) { 3855 if (obj instanceof SharedUserSetting) { 3856 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 3857 } else if (obj instanceof PackageSetting) { 3858 s1 = ((PackageSetting)obj).signatures.mSignatures; 3859 } else { 3860 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3861 } 3862 } else { 3863 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3864 } 3865 obj = mSettings.getUserIdLPr(uid2); 3866 if (obj != null) { 3867 if (obj instanceof SharedUserSetting) { 3868 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 3869 } else if (obj instanceof PackageSetting) { 3870 s2 = ((PackageSetting)obj).signatures.mSignatures; 3871 } else { 3872 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3873 } 3874 } else { 3875 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3876 } 3877 return compareSignatures(s1, s2); 3878 } 3879 } 3880 3881 private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) { 3882 final long identity = Binder.clearCallingIdentity(); 3883 try { 3884 if (sb instanceof SharedUserSetting) { 3885 SharedUserSetting sus = (SharedUserSetting) sb; 3886 final int packageCount = sus.packages.size(); 3887 for (int i = 0; i < packageCount; i++) { 3888 PackageSetting susPs = sus.packages.valueAt(i); 3889 if (userId == UserHandle.USER_ALL) { 3890 killApplication(susPs.pkg.packageName, susPs.appId, reason); 3891 } else { 3892 final int uid = UserHandle.getUid(userId, susPs.appId); 3893 killUid(uid, reason); 3894 } 3895 } 3896 } else if (sb instanceof PackageSetting) { 3897 PackageSetting ps = (PackageSetting) sb; 3898 if (userId == UserHandle.USER_ALL) { 3899 killApplication(ps.pkg.packageName, ps.appId, reason); 3900 } else { 3901 final int uid = UserHandle.getUid(userId, ps.appId); 3902 killUid(uid, reason); 3903 } 3904 } 3905 } finally { 3906 Binder.restoreCallingIdentity(identity); 3907 } 3908 } 3909 3910 private static void killUid(int uid, String reason) { 3911 IActivityManager am = ActivityManagerNative.getDefault(); 3912 if (am != null) { 3913 try { 3914 am.killUid(uid, reason); 3915 } catch (RemoteException e) { 3916 /* ignore - same process */ 3917 } 3918 } 3919 } 3920 3921 /** 3922 * Compares two sets of signatures. Returns: 3923 * <br /> 3924 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 3925 * <br /> 3926 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 3927 * <br /> 3928 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 3929 * <br /> 3930 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 3931 * <br /> 3932 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 3933 */ 3934 static int compareSignatures(Signature[] s1, Signature[] s2) { 3935 if (s1 == null) { 3936 return s2 == null 3937 ? PackageManager.SIGNATURE_NEITHER_SIGNED 3938 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 3939 } 3940 3941 if (s2 == null) { 3942 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 3943 } 3944 3945 if (s1.length != s2.length) { 3946 return PackageManager.SIGNATURE_NO_MATCH; 3947 } 3948 3949 // Since both signature sets are of size 1, we can compare without HashSets. 3950 if (s1.length == 1) { 3951 return s1[0].equals(s2[0]) ? 3952 PackageManager.SIGNATURE_MATCH : 3953 PackageManager.SIGNATURE_NO_MATCH; 3954 } 3955 3956 ArraySet<Signature> set1 = new ArraySet<Signature>(); 3957 for (Signature sig : s1) { 3958 set1.add(sig); 3959 } 3960 ArraySet<Signature> set2 = new ArraySet<Signature>(); 3961 for (Signature sig : s2) { 3962 set2.add(sig); 3963 } 3964 // Make sure s2 contains all signatures in s1. 3965 if (set1.equals(set2)) { 3966 return PackageManager.SIGNATURE_MATCH; 3967 } 3968 return PackageManager.SIGNATURE_NO_MATCH; 3969 } 3970 3971 /** 3972 * If the database version for this type of package (internal storage or 3973 * external storage) is less than the version where package signatures 3974 * were updated, return true. 3975 */ 3976 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3977 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 3978 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 3979 } 3980 3981 /** 3982 * Used for backward compatibility to make sure any packages with 3983 * certificate chains get upgraded to the new style. {@code existingSigs} 3984 * will be in the old format (since they were stored on disk from before the 3985 * system upgrade) and {@code scannedSigs} will be in the newer format. 3986 */ 3987 private int compareSignaturesCompat(PackageSignatures existingSigs, 3988 PackageParser.Package scannedPkg) { 3989 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 3990 return PackageManager.SIGNATURE_NO_MATCH; 3991 } 3992 3993 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 3994 for (Signature sig : existingSigs.mSignatures) { 3995 existingSet.add(sig); 3996 } 3997 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 3998 for (Signature sig : scannedPkg.mSignatures) { 3999 try { 4000 Signature[] chainSignatures = sig.getChainSignatures(); 4001 for (Signature chainSig : chainSignatures) { 4002 scannedCompatSet.add(chainSig); 4003 } 4004 } catch (CertificateEncodingException e) { 4005 scannedCompatSet.add(sig); 4006 } 4007 } 4008 /* 4009 * Make sure the expanded scanned set contains all signatures in the 4010 * existing one. 4011 */ 4012 if (scannedCompatSet.equals(existingSet)) { 4013 // Migrate the old signatures to the new scheme. 4014 existingSigs.assignSignatures(scannedPkg.mSignatures); 4015 // The new KeySets will be re-added later in the scanning process. 4016 synchronized (mPackages) { 4017 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4018 } 4019 return PackageManager.SIGNATURE_MATCH; 4020 } 4021 return PackageManager.SIGNATURE_NO_MATCH; 4022 } 4023 4024 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4025 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4026 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4027 } 4028 4029 private int compareSignaturesRecover(PackageSignatures existingSigs, 4030 PackageParser.Package scannedPkg) { 4031 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4032 return PackageManager.SIGNATURE_NO_MATCH; 4033 } 4034 4035 String msg = null; 4036 try { 4037 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4038 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4039 + scannedPkg.packageName); 4040 return PackageManager.SIGNATURE_MATCH; 4041 } 4042 } catch (CertificateException e) { 4043 msg = e.getMessage(); 4044 } 4045 4046 logCriticalInfo(Log.INFO, 4047 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4048 return PackageManager.SIGNATURE_NO_MATCH; 4049 } 4050 4051 @Override 4052 public String[] getPackagesForUid(int uid) { 4053 uid = UserHandle.getAppId(uid); 4054 // reader 4055 synchronized (mPackages) { 4056 Object obj = mSettings.getUserIdLPr(uid); 4057 if (obj instanceof SharedUserSetting) { 4058 final SharedUserSetting sus = (SharedUserSetting) obj; 4059 final int N = sus.packages.size(); 4060 final String[] res = new String[N]; 4061 final Iterator<PackageSetting> it = sus.packages.iterator(); 4062 int i = 0; 4063 while (it.hasNext()) { 4064 res[i++] = it.next().name; 4065 } 4066 return res; 4067 } else if (obj instanceof PackageSetting) { 4068 final PackageSetting ps = (PackageSetting) obj; 4069 return new String[] { ps.name }; 4070 } 4071 } 4072 return null; 4073 } 4074 4075 @Override 4076 public String getNameForUid(int uid) { 4077 // reader 4078 synchronized (mPackages) { 4079 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4080 if (obj instanceof SharedUserSetting) { 4081 final SharedUserSetting sus = (SharedUserSetting) obj; 4082 return sus.name + ":" + sus.userId; 4083 } else if (obj instanceof PackageSetting) { 4084 final PackageSetting ps = (PackageSetting) obj; 4085 return ps.name; 4086 } 4087 } 4088 return null; 4089 } 4090 4091 @Override 4092 public int getUidForSharedUser(String sharedUserName) { 4093 if(sharedUserName == null) { 4094 return -1; 4095 } 4096 // reader 4097 synchronized (mPackages) { 4098 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4099 if (suid == null) { 4100 return -1; 4101 } 4102 return suid.userId; 4103 } 4104 } 4105 4106 @Override 4107 public int getFlagsForUid(int uid) { 4108 synchronized (mPackages) { 4109 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4110 if (obj instanceof SharedUserSetting) { 4111 final SharedUserSetting sus = (SharedUserSetting) obj; 4112 return sus.pkgFlags; 4113 } else if (obj instanceof PackageSetting) { 4114 final PackageSetting ps = (PackageSetting) obj; 4115 return ps.pkgFlags; 4116 } 4117 } 4118 return 0; 4119 } 4120 4121 @Override 4122 public int getPrivateFlagsForUid(int uid) { 4123 synchronized (mPackages) { 4124 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4125 if (obj instanceof SharedUserSetting) { 4126 final SharedUserSetting sus = (SharedUserSetting) obj; 4127 return sus.pkgPrivateFlags; 4128 } else if (obj instanceof PackageSetting) { 4129 final PackageSetting ps = (PackageSetting) obj; 4130 return ps.pkgPrivateFlags; 4131 } 4132 } 4133 return 0; 4134 } 4135 4136 @Override 4137 public boolean isUidPrivileged(int uid) { 4138 uid = UserHandle.getAppId(uid); 4139 // reader 4140 synchronized (mPackages) { 4141 Object obj = mSettings.getUserIdLPr(uid); 4142 if (obj instanceof SharedUserSetting) { 4143 final SharedUserSetting sus = (SharedUserSetting) obj; 4144 final Iterator<PackageSetting> it = sus.packages.iterator(); 4145 while (it.hasNext()) { 4146 if (it.next().isPrivileged()) { 4147 return true; 4148 } 4149 } 4150 } else if (obj instanceof PackageSetting) { 4151 final PackageSetting ps = (PackageSetting) obj; 4152 return ps.isPrivileged(); 4153 } 4154 } 4155 return false; 4156 } 4157 4158 @Override 4159 public String[] getAppOpPermissionPackages(String permissionName) { 4160 synchronized (mPackages) { 4161 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4162 if (pkgs == null) { 4163 return null; 4164 } 4165 return pkgs.toArray(new String[pkgs.size()]); 4166 } 4167 } 4168 4169 @Override 4170 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4171 int flags, int userId) { 4172 if (!sUserManager.exists(userId)) return null; 4173 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 4174 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4175 return chooseBestActivity(intent, resolvedType, flags, query, userId); 4176 } 4177 4178 @Override 4179 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4180 IntentFilter filter, int match, ComponentName activity) { 4181 final int userId = UserHandle.getCallingUserId(); 4182 if (DEBUG_PREFERRED) { 4183 Log.v(TAG, "setLastChosenActivity intent=" + intent 4184 + " resolvedType=" + resolvedType 4185 + " flags=" + flags 4186 + " filter=" + filter 4187 + " match=" + match 4188 + " activity=" + activity); 4189 filter.dump(new PrintStreamPrinter(System.out), " "); 4190 } 4191 intent.setComponent(null); 4192 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4193 // Find any earlier preferred or last chosen entries and nuke them 4194 findPreferredActivity(intent, resolvedType, 4195 flags, query, 0, false, true, false, userId); 4196 // Add the new activity as the last chosen for this filter 4197 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4198 "Setting last chosen"); 4199 } 4200 4201 @Override 4202 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4203 final int userId = UserHandle.getCallingUserId(); 4204 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4205 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4206 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4207 false, false, false, userId); 4208 } 4209 4210 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4211 int flags, List<ResolveInfo> query, int userId) { 4212 if (query != null) { 4213 final int N = query.size(); 4214 if (N == 1) { 4215 return query.get(0); 4216 } else if (N > 1) { 4217 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4218 // If there is more than one activity with the same priority, 4219 // then let the user decide between them. 4220 ResolveInfo r0 = query.get(0); 4221 ResolveInfo r1 = query.get(1); 4222 if (DEBUG_INTENT_MATCHING || debug) { 4223 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4224 + r1.activityInfo.name + "=" + r1.priority); 4225 } 4226 // If the first activity has a higher priority, or a different 4227 // default, then it is always desireable to pick it. 4228 if (r0.priority != r1.priority 4229 || r0.preferredOrder != r1.preferredOrder 4230 || r0.isDefault != r1.isDefault) { 4231 return query.get(0); 4232 } 4233 // If we have saved a preference for a preferred activity for 4234 // this Intent, use that. 4235 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4236 flags, query, r0.priority, true, false, debug, userId); 4237 if (ri != null) { 4238 return ri; 4239 } 4240 if (userId != 0) { 4241 ri = new ResolveInfo(mResolveInfo); 4242 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4243 ri.activityInfo.applicationInfo = new ApplicationInfo( 4244 ri.activityInfo.applicationInfo); 4245 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4246 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4247 return ri; 4248 } 4249 return mResolveInfo; 4250 } 4251 } 4252 return null; 4253 } 4254 4255 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4256 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4257 final int N = query.size(); 4258 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4259 .get(userId); 4260 // Get the list of persistent preferred activities that handle the intent 4261 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4262 List<PersistentPreferredActivity> pprefs = ppir != null 4263 ? ppir.queryIntent(intent, resolvedType, 4264 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4265 : null; 4266 if (pprefs != null && pprefs.size() > 0) { 4267 final int M = pprefs.size(); 4268 for (int i=0; i<M; i++) { 4269 final PersistentPreferredActivity ppa = pprefs.get(i); 4270 if (DEBUG_PREFERRED || debug) { 4271 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4272 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4273 + "\n component=" + ppa.mComponent); 4274 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4275 } 4276 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4277 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 4278 if (DEBUG_PREFERRED || debug) { 4279 Slog.v(TAG, "Found persistent preferred activity:"); 4280 if (ai != null) { 4281 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4282 } else { 4283 Slog.v(TAG, " null"); 4284 } 4285 } 4286 if (ai == null) { 4287 // This previously registered persistent preferred activity 4288 // component is no longer known. Ignore it and do NOT remove it. 4289 continue; 4290 } 4291 for (int j=0; j<N; j++) { 4292 final ResolveInfo ri = query.get(j); 4293 if (!ri.activityInfo.applicationInfo.packageName 4294 .equals(ai.applicationInfo.packageName)) { 4295 continue; 4296 } 4297 if (!ri.activityInfo.name.equals(ai.name)) { 4298 continue; 4299 } 4300 // Found a persistent preference that can handle the intent. 4301 if (DEBUG_PREFERRED || debug) { 4302 Slog.v(TAG, "Returning persistent preferred activity: " + 4303 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4304 } 4305 return ri; 4306 } 4307 } 4308 } 4309 return null; 4310 } 4311 4312 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4313 List<ResolveInfo> query, int priority, boolean always, 4314 boolean removeMatches, boolean debug, int userId) { 4315 if (!sUserManager.exists(userId)) return null; 4316 // writer 4317 synchronized (mPackages) { 4318 if (intent.getSelector() != null) { 4319 intent = intent.getSelector(); 4320 } 4321 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4322 4323 // Try to find a matching persistent preferred activity. 4324 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4325 debug, userId); 4326 4327 // If a persistent preferred activity matched, use it. 4328 if (pri != null) { 4329 return pri; 4330 } 4331 4332 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4333 // Get the list of preferred activities that handle the intent 4334 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4335 List<PreferredActivity> prefs = pir != null 4336 ? pir.queryIntent(intent, resolvedType, 4337 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4338 : null; 4339 if (prefs != null && prefs.size() > 0) { 4340 boolean changed = false; 4341 try { 4342 // First figure out how good the original match set is. 4343 // We will only allow preferred activities that came 4344 // from the same match quality. 4345 int match = 0; 4346 4347 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4348 4349 final int N = query.size(); 4350 for (int j=0; j<N; j++) { 4351 final ResolveInfo ri = query.get(j); 4352 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4353 + ": 0x" + Integer.toHexString(match)); 4354 if (ri.match > match) { 4355 match = ri.match; 4356 } 4357 } 4358 4359 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4360 + Integer.toHexString(match)); 4361 4362 match &= IntentFilter.MATCH_CATEGORY_MASK; 4363 final int M = prefs.size(); 4364 for (int i=0; i<M; i++) { 4365 final PreferredActivity pa = prefs.get(i); 4366 if (DEBUG_PREFERRED || debug) { 4367 Slog.v(TAG, "Checking PreferredActivity ds=" 4368 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4369 + "\n component=" + pa.mPref.mComponent); 4370 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4371 } 4372 if (pa.mPref.mMatch != match) { 4373 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4374 + Integer.toHexString(pa.mPref.mMatch)); 4375 continue; 4376 } 4377 // If it's not an "always" type preferred activity and that's what we're 4378 // looking for, skip it. 4379 if (always && !pa.mPref.mAlways) { 4380 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4381 continue; 4382 } 4383 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4384 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 4385 if (DEBUG_PREFERRED || debug) { 4386 Slog.v(TAG, "Found preferred activity:"); 4387 if (ai != null) { 4388 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4389 } else { 4390 Slog.v(TAG, " null"); 4391 } 4392 } 4393 if (ai == null) { 4394 // This previously registered preferred activity 4395 // component is no longer known. Most likely an update 4396 // to the app was installed and in the new version this 4397 // component no longer exists. Clean it up by removing 4398 // it from the preferred activities list, and skip it. 4399 Slog.w(TAG, "Removing dangling preferred activity: " 4400 + pa.mPref.mComponent); 4401 pir.removeFilter(pa); 4402 changed = true; 4403 continue; 4404 } 4405 for (int j=0; j<N; j++) { 4406 final ResolveInfo ri = query.get(j); 4407 if (!ri.activityInfo.applicationInfo.packageName 4408 .equals(ai.applicationInfo.packageName)) { 4409 continue; 4410 } 4411 if (!ri.activityInfo.name.equals(ai.name)) { 4412 continue; 4413 } 4414 4415 if (removeMatches) { 4416 pir.removeFilter(pa); 4417 changed = true; 4418 if (DEBUG_PREFERRED) { 4419 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4420 } 4421 break; 4422 } 4423 4424 // Okay we found a previously set preferred or last chosen app. 4425 // If the result set is different from when this 4426 // was created, we need to clear it and re-ask the 4427 // user their preference, if we're looking for an "always" type entry. 4428 if (always && !pa.mPref.sameSet(query)) { 4429 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4430 + intent + " type " + resolvedType); 4431 if (DEBUG_PREFERRED) { 4432 Slog.v(TAG, "Removing preferred activity since set changed " 4433 + pa.mPref.mComponent); 4434 } 4435 pir.removeFilter(pa); 4436 // Re-add the filter as a "last chosen" entry (!always) 4437 PreferredActivity lastChosen = new PreferredActivity( 4438 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4439 pir.addFilter(lastChosen); 4440 changed = true; 4441 return null; 4442 } 4443 4444 // Yay! Either the set matched or we're looking for the last chosen 4445 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4446 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4447 return ri; 4448 } 4449 } 4450 } finally { 4451 if (changed) { 4452 if (DEBUG_PREFERRED) { 4453 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 4454 } 4455 scheduleWritePackageRestrictionsLocked(userId); 4456 } 4457 } 4458 } 4459 } 4460 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 4461 return null; 4462 } 4463 4464 /* 4465 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 4466 */ 4467 @Override 4468 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 4469 int targetUserId) { 4470 mContext.enforceCallingOrSelfPermission( 4471 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 4472 List<CrossProfileIntentFilter> matches = 4473 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 4474 if (matches != null) { 4475 int size = matches.size(); 4476 for (int i = 0; i < size; i++) { 4477 if (matches.get(i).getTargetUserId() == targetUserId) return true; 4478 } 4479 } 4480 if (hasWebURI(intent)) { 4481 // cross-profile app linking works only towards the parent. 4482 final UserInfo parent = getProfileParent(sourceUserId); 4483 synchronized(mPackages) { 4484 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 4485 intent, resolvedType, 0, sourceUserId, parent.id); 4486 return xpDomainInfo != null; 4487 } 4488 } 4489 return false; 4490 } 4491 4492 private UserInfo getProfileParent(int userId) { 4493 final long identity = Binder.clearCallingIdentity(); 4494 try { 4495 return sUserManager.getProfileParent(userId); 4496 } finally { 4497 Binder.restoreCallingIdentity(identity); 4498 } 4499 } 4500 4501 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 4502 String resolvedType, int userId) { 4503 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 4504 if (resolver != null) { 4505 return resolver.queryIntent(intent, resolvedType, false, userId); 4506 } 4507 return null; 4508 } 4509 4510 @Override 4511 public List<ResolveInfo> queryIntentActivities(Intent intent, 4512 String resolvedType, int flags, int userId) { 4513 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4514 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 4515 ComponentName comp = intent.getComponent(); 4516 if (comp == null) { 4517 if (intent.getSelector() != null) { 4518 intent = intent.getSelector(); 4519 comp = intent.getComponent(); 4520 } 4521 } 4522 4523 if (comp != null) { 4524 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4525 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 4526 if (ai != null) { 4527 final ResolveInfo ri = new ResolveInfo(); 4528 ri.activityInfo = ai; 4529 list.add(ri); 4530 } 4531 return list; 4532 } 4533 4534 // reader 4535 synchronized (mPackages) { 4536 final String pkgName = intent.getPackage(); 4537 if (pkgName == null) { 4538 List<CrossProfileIntentFilter> matchingFilters = 4539 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 4540 // Check for results that need to skip the current profile. 4541 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 4542 resolvedType, flags, userId); 4543 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 4544 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 4545 result.add(xpResolveInfo); 4546 return filterIfNotPrimaryUser(result, userId); 4547 } 4548 4549 // Check for results in the current profile. 4550 List<ResolveInfo> result = mActivities.queryIntent( 4551 intent, resolvedType, flags, userId); 4552 4553 // Check for cross profile results. 4554 xpResolveInfo = queryCrossProfileIntents( 4555 matchingFilters, intent, resolvedType, flags, userId); 4556 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 4557 result.add(xpResolveInfo); 4558 Collections.sort(result, mResolvePrioritySorter); 4559 } 4560 result = filterIfNotPrimaryUser(result, userId); 4561 if (hasWebURI(intent)) { 4562 CrossProfileDomainInfo xpDomainInfo = null; 4563 final UserInfo parent = getProfileParent(userId); 4564 if (parent != null) { 4565 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 4566 flags, userId, parent.id); 4567 } 4568 if (xpDomainInfo != null) { 4569 if (xpResolveInfo != null) { 4570 // If we didn't remove it, the cross-profile ResolveInfo would be twice 4571 // in the result. 4572 result.remove(xpResolveInfo); 4573 } 4574 if (result.size() == 0) { 4575 result.add(xpDomainInfo.resolveInfo); 4576 return result; 4577 } 4578 } else if (result.size() <= 1) { 4579 return result; 4580 } 4581 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 4582 xpDomainInfo, userId); 4583 Collections.sort(result, mResolvePrioritySorter); 4584 } 4585 return result; 4586 } 4587 final PackageParser.Package pkg = mPackages.get(pkgName); 4588 if (pkg != null) { 4589 return filterIfNotPrimaryUser( 4590 mActivities.queryIntentForPackage( 4591 intent, resolvedType, flags, pkg.activities, userId), 4592 userId); 4593 } 4594 return new ArrayList<ResolveInfo>(); 4595 } 4596 } 4597 4598 private static class CrossProfileDomainInfo { 4599 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 4600 ResolveInfo resolveInfo; 4601 /* Best domain verification status of the activities found in the other profile */ 4602 int bestDomainVerificationStatus; 4603 } 4604 4605 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 4606 String resolvedType, int flags, int sourceUserId, int parentUserId) { 4607 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 4608 sourceUserId)) { 4609 return null; 4610 } 4611 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4612 resolvedType, flags, parentUserId); 4613 4614 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 4615 return null; 4616 } 4617 CrossProfileDomainInfo result = null; 4618 int size = resultTargetUser.size(); 4619 for (int i = 0; i < size; i++) { 4620 ResolveInfo riTargetUser = resultTargetUser.get(i); 4621 // Intent filter verification is only for filters that specify a host. So don't return 4622 // those that handle all web uris. 4623 if (riTargetUser.handleAllWebDataURI) { 4624 continue; 4625 } 4626 String packageName = riTargetUser.activityInfo.packageName; 4627 PackageSetting ps = mSettings.mPackages.get(packageName); 4628 if (ps == null) { 4629 continue; 4630 } 4631 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 4632 int status = (int)(verificationState >> 32); 4633 if (result == null) { 4634 result = new CrossProfileDomainInfo(); 4635 result.resolveInfo = 4636 createForwardingResolveInfo(null, sourceUserId, parentUserId); 4637 result.bestDomainVerificationStatus = status; 4638 } else { 4639 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 4640 result.bestDomainVerificationStatus); 4641 } 4642 } 4643 // Don't consider matches with status NEVER across profiles. 4644 if (result != null && result.bestDomainVerificationStatus 4645 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4646 return null; 4647 } 4648 return result; 4649 } 4650 4651 /** 4652 * Verification statuses are ordered from the worse to the best, except for 4653 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 4654 */ 4655 private int bestDomainVerificationStatus(int status1, int status2) { 4656 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4657 return status2; 4658 } 4659 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4660 return status1; 4661 } 4662 return (int) MathUtils.max(status1, status2); 4663 } 4664 4665 private boolean isUserEnabled(int userId) { 4666 long callingId = Binder.clearCallingIdentity(); 4667 try { 4668 UserInfo userInfo = sUserManager.getUserInfo(userId); 4669 return userInfo != null && userInfo.isEnabled(); 4670 } finally { 4671 Binder.restoreCallingIdentity(callingId); 4672 } 4673 } 4674 4675 /** 4676 * Filter out activities with primaryUserOnly flag set, when current user is not the owner. 4677 * 4678 * @return filtered list 4679 */ 4680 private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) { 4681 if (userId == UserHandle.USER_OWNER) { 4682 return resolveInfos; 4683 } 4684 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 4685 ResolveInfo info = resolveInfos.get(i); 4686 if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 4687 resolveInfos.remove(i); 4688 } 4689 } 4690 return resolveInfos; 4691 } 4692 4693 private static boolean hasWebURI(Intent intent) { 4694 if (intent.getData() == null) { 4695 return false; 4696 } 4697 final String scheme = intent.getScheme(); 4698 if (TextUtils.isEmpty(scheme)) { 4699 return false; 4700 } 4701 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 4702 } 4703 4704 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 4705 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 4706 int userId) { 4707 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 4708 4709 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 4710 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 4711 candidates.size()); 4712 } 4713 4714 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 4715 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 4716 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 4717 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 4718 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 4719 4720 synchronized (mPackages) { 4721 final int count = candidates.size(); 4722 // First, try to use linked apps. Partition the candidates into four lists: 4723 // one for the final results, one for the "do not use ever", one for "undefined status" 4724 // and finally one for "browser app type". 4725 for (int n=0; n<count; n++) { 4726 ResolveInfo info = candidates.get(n); 4727 String packageName = info.activityInfo.packageName; 4728 PackageSetting ps = mSettings.mPackages.get(packageName); 4729 if (ps != null) { 4730 // Add to the special match all list (Browser use case) 4731 if (info.handleAllWebDataURI) { 4732 matchAllList.add(info); 4733 continue; 4734 } 4735 // Try to get the status from User settings first 4736 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4737 int status = (int)(packedStatus >> 32); 4738 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 4739 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 4740 if (DEBUG_DOMAIN_VERIFICATION) { 4741 Slog.i(TAG, " + always: " + info.activityInfo.packageName 4742 + " : linkgen=" + linkGeneration); 4743 } 4744 // Use link-enabled generation as preferredOrder, i.e. 4745 // prefer newly-enabled over earlier-enabled. 4746 info.preferredOrder = linkGeneration; 4747 alwaysList.add(info); 4748 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4749 if (DEBUG_DOMAIN_VERIFICATION) { 4750 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 4751 } 4752 neverList.add(info); 4753 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 4754 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 4755 if (DEBUG_DOMAIN_VERIFICATION) { 4756 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 4757 } 4758 undefinedList.add(info); 4759 } 4760 } 4761 } 4762 // First try to add the "always" resolution(s) for the current user, if any 4763 if (alwaysList.size() > 0) { 4764 result.addAll(alwaysList); 4765 // if there is an "always" for the parent user, add it. 4766 } else if (xpDomainInfo != null && xpDomainInfo.bestDomainVerificationStatus 4767 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 4768 result.add(xpDomainInfo.resolveInfo); 4769 } else { 4770 // Add all undefined Apps as we want them to appear in the Disambiguation dialog. 4771 result.addAll(undefinedList); 4772 if (xpDomainInfo != null && ( 4773 xpDomainInfo.bestDomainVerificationStatus 4774 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED 4775 || xpDomainInfo.bestDomainVerificationStatus 4776 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK)) { 4777 result.add(xpDomainInfo.resolveInfo); 4778 } 4779 // Also add Browsers (all of them or only the default one) 4780 if ((matchFlags & MATCH_ALL) != 0) { 4781 result.addAll(matchAllList); 4782 } else { 4783 // Browser/generic handling case. If there's a default browser, go straight 4784 // to that (but only if there is no other higher-priority match). 4785 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 4786 int maxMatchPrio = 0; 4787 ResolveInfo defaultBrowserMatch = null; 4788 final int numCandidates = matchAllList.size(); 4789 for (int n = 0; n < numCandidates; n++) { 4790 ResolveInfo info = matchAllList.get(n); 4791 // track the highest overall match priority... 4792 if (info.priority > maxMatchPrio) { 4793 maxMatchPrio = info.priority; 4794 } 4795 // ...and the highest-priority default browser match 4796 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 4797 if (defaultBrowserMatch == null 4798 || (defaultBrowserMatch.priority < info.priority)) { 4799 if (debug) { 4800 Slog.v(TAG, "Considering default browser match " + info); 4801 } 4802 defaultBrowserMatch = info; 4803 } 4804 } 4805 } 4806 if (defaultBrowserMatch != null 4807 && defaultBrowserMatch.priority >= maxMatchPrio 4808 && !TextUtils.isEmpty(defaultBrowserPackageName)) 4809 { 4810 if (debug) { 4811 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 4812 } 4813 result.add(defaultBrowserMatch); 4814 } else { 4815 result.addAll(matchAllList); 4816 } 4817 } 4818 4819 // If there is nothing selected, add all candidates and remove the ones that the user 4820 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 4821 if (result.size() == 0) { 4822 result.addAll(candidates); 4823 result.removeAll(neverList); 4824 } 4825 } 4826 } 4827 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 4828 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 4829 result.size()); 4830 for (ResolveInfo info : result) { 4831 Slog.v(TAG, " + " + info.activityInfo); 4832 } 4833 } 4834 return result; 4835 } 4836 4837 // Returns a packed value as a long: 4838 // 4839 // high 'int'-sized word: link status: undefined/ask/never/always. 4840 // low 'int'-sized word: relative priority among 'always' results. 4841 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 4842 long result = ps.getDomainVerificationStatusForUser(userId); 4843 // if none available, get the master status 4844 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4845 if (ps.getIntentFilterVerificationInfo() != null) { 4846 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 4847 } 4848 } 4849 return result; 4850 } 4851 4852 private ResolveInfo querySkipCurrentProfileIntents( 4853 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4854 int flags, int sourceUserId) { 4855 if (matchingFilters != null) { 4856 int size = matchingFilters.size(); 4857 for (int i = 0; i < size; i ++) { 4858 CrossProfileIntentFilter filter = matchingFilters.get(i); 4859 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 4860 // Checking if there are activities in the target user that can handle the 4861 // intent. 4862 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4863 flags, sourceUserId); 4864 if (resolveInfo != null) { 4865 return resolveInfo; 4866 } 4867 } 4868 } 4869 } 4870 return null; 4871 } 4872 4873 // Return matching ResolveInfo if any for skip current profile intent filters. 4874 private ResolveInfo queryCrossProfileIntents( 4875 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4876 int flags, int sourceUserId) { 4877 if (matchingFilters != null) { 4878 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 4879 // match the same intent. For performance reasons, it is better not to 4880 // run queryIntent twice for the same userId 4881 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 4882 int size = matchingFilters.size(); 4883 for (int i = 0; i < size; i++) { 4884 CrossProfileIntentFilter filter = matchingFilters.get(i); 4885 int targetUserId = filter.getTargetUserId(); 4886 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 4887 && !alreadyTriedUserIds.get(targetUserId)) { 4888 // Checking if there are activities in the target user that can handle the 4889 // intent. 4890 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4891 flags, sourceUserId); 4892 if (resolveInfo != null) return resolveInfo; 4893 alreadyTriedUserIds.put(targetUserId, true); 4894 } 4895 } 4896 } 4897 return null; 4898 } 4899 4900 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 4901 String resolvedType, int flags, int sourceUserId) { 4902 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4903 resolvedType, flags, filter.getTargetUserId()); 4904 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 4905 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 4906 } 4907 return null; 4908 } 4909 4910 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 4911 int sourceUserId, int targetUserId) { 4912 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 4913 String className; 4914 if (targetUserId == UserHandle.USER_OWNER) { 4915 className = FORWARD_INTENT_TO_USER_OWNER; 4916 } else { 4917 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 4918 } 4919 ComponentName forwardingActivityComponentName = new ComponentName( 4920 mAndroidApplication.packageName, className); 4921 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 4922 sourceUserId); 4923 if (targetUserId == UserHandle.USER_OWNER) { 4924 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 4925 forwardingResolveInfo.noResourceId = true; 4926 } 4927 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 4928 forwardingResolveInfo.priority = 0; 4929 forwardingResolveInfo.preferredOrder = 0; 4930 forwardingResolveInfo.match = 0; 4931 forwardingResolveInfo.isDefault = true; 4932 forwardingResolveInfo.filter = filter; 4933 forwardingResolveInfo.targetUserId = targetUserId; 4934 return forwardingResolveInfo; 4935 } 4936 4937 @Override 4938 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 4939 Intent[] specifics, String[] specificTypes, Intent intent, 4940 String resolvedType, int flags, int userId) { 4941 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4942 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 4943 false, "query intent activity options"); 4944 final String resultsAction = intent.getAction(); 4945 4946 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 4947 | PackageManager.GET_RESOLVED_FILTER, userId); 4948 4949 if (DEBUG_INTENT_MATCHING) { 4950 Log.v(TAG, "Query " + intent + ": " + results); 4951 } 4952 4953 int specificsPos = 0; 4954 int N; 4955 4956 // todo: note that the algorithm used here is O(N^2). This 4957 // isn't a problem in our current environment, but if we start running 4958 // into situations where we have more than 5 or 10 matches then this 4959 // should probably be changed to something smarter... 4960 4961 // First we go through and resolve each of the specific items 4962 // that were supplied, taking care of removing any corresponding 4963 // duplicate items in the generic resolve list. 4964 if (specifics != null) { 4965 for (int i=0; i<specifics.length; i++) { 4966 final Intent sintent = specifics[i]; 4967 if (sintent == null) { 4968 continue; 4969 } 4970 4971 if (DEBUG_INTENT_MATCHING) { 4972 Log.v(TAG, "Specific #" + i + ": " + sintent); 4973 } 4974 4975 String action = sintent.getAction(); 4976 if (resultsAction != null && resultsAction.equals(action)) { 4977 // If this action was explicitly requested, then don't 4978 // remove things that have it. 4979 action = null; 4980 } 4981 4982 ResolveInfo ri = null; 4983 ActivityInfo ai = null; 4984 4985 ComponentName comp = sintent.getComponent(); 4986 if (comp == null) { 4987 ri = resolveIntent( 4988 sintent, 4989 specificTypes != null ? specificTypes[i] : null, 4990 flags, userId); 4991 if (ri == null) { 4992 continue; 4993 } 4994 if (ri == mResolveInfo) { 4995 // ACK! Must do something better with this. 4996 } 4997 ai = ri.activityInfo; 4998 comp = new ComponentName(ai.applicationInfo.packageName, 4999 ai.name); 5000 } else { 5001 ai = getActivityInfo(comp, flags, userId); 5002 if (ai == null) { 5003 continue; 5004 } 5005 } 5006 5007 // Look for any generic query activities that are duplicates 5008 // of this specific one, and remove them from the results. 5009 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5010 N = results.size(); 5011 int j; 5012 for (j=specificsPos; j<N; j++) { 5013 ResolveInfo sri = results.get(j); 5014 if ((sri.activityInfo.name.equals(comp.getClassName()) 5015 && sri.activityInfo.applicationInfo.packageName.equals( 5016 comp.getPackageName())) 5017 || (action != null && sri.filter.matchAction(action))) { 5018 results.remove(j); 5019 if (DEBUG_INTENT_MATCHING) Log.v( 5020 TAG, "Removing duplicate item from " + j 5021 + " due to specific " + specificsPos); 5022 if (ri == null) { 5023 ri = sri; 5024 } 5025 j--; 5026 N--; 5027 } 5028 } 5029 5030 // Add this specific item to its proper place. 5031 if (ri == null) { 5032 ri = new ResolveInfo(); 5033 ri.activityInfo = ai; 5034 } 5035 results.add(specificsPos, ri); 5036 ri.specificIndex = i; 5037 specificsPos++; 5038 } 5039 } 5040 5041 // Now we go through the remaining generic results and remove any 5042 // duplicate actions that are found here. 5043 N = results.size(); 5044 for (int i=specificsPos; i<N-1; i++) { 5045 final ResolveInfo rii = results.get(i); 5046 if (rii.filter == null) { 5047 continue; 5048 } 5049 5050 // Iterate over all of the actions of this result's intent 5051 // filter... typically this should be just one. 5052 final Iterator<String> it = rii.filter.actionsIterator(); 5053 if (it == null) { 5054 continue; 5055 } 5056 while (it.hasNext()) { 5057 final String action = it.next(); 5058 if (resultsAction != null && resultsAction.equals(action)) { 5059 // If this action was explicitly requested, then don't 5060 // remove things that have it. 5061 continue; 5062 } 5063 for (int j=i+1; j<N; j++) { 5064 final ResolveInfo rij = results.get(j); 5065 if (rij.filter != null && rij.filter.hasAction(action)) { 5066 results.remove(j); 5067 if (DEBUG_INTENT_MATCHING) Log.v( 5068 TAG, "Removing duplicate item from " + j 5069 + " due to action " + action + " at " + i); 5070 j--; 5071 N--; 5072 } 5073 } 5074 } 5075 5076 // If the caller didn't request filter information, drop it now 5077 // so we don't have to marshall/unmarshall it. 5078 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5079 rii.filter = null; 5080 } 5081 } 5082 5083 // Filter out the caller activity if so requested. 5084 if (caller != null) { 5085 N = results.size(); 5086 for (int i=0; i<N; i++) { 5087 ActivityInfo ainfo = results.get(i).activityInfo; 5088 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5089 && caller.getClassName().equals(ainfo.name)) { 5090 results.remove(i); 5091 break; 5092 } 5093 } 5094 } 5095 5096 // If the caller didn't request filter information, 5097 // drop them now so we don't have to 5098 // marshall/unmarshall it. 5099 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5100 N = results.size(); 5101 for (int i=0; i<N; i++) { 5102 results.get(i).filter = null; 5103 } 5104 } 5105 5106 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5107 return results; 5108 } 5109 5110 @Override 5111 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 5112 int userId) { 5113 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5114 ComponentName comp = intent.getComponent(); 5115 if (comp == null) { 5116 if (intent.getSelector() != null) { 5117 intent = intent.getSelector(); 5118 comp = intent.getComponent(); 5119 } 5120 } 5121 if (comp != null) { 5122 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5123 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5124 if (ai != null) { 5125 ResolveInfo ri = new ResolveInfo(); 5126 ri.activityInfo = ai; 5127 list.add(ri); 5128 } 5129 return list; 5130 } 5131 5132 // reader 5133 synchronized (mPackages) { 5134 String pkgName = intent.getPackage(); 5135 if (pkgName == null) { 5136 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5137 } 5138 final PackageParser.Package pkg = mPackages.get(pkgName); 5139 if (pkg != null) { 5140 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5141 userId); 5142 } 5143 return null; 5144 } 5145 } 5146 5147 @Override 5148 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5149 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 5150 if (!sUserManager.exists(userId)) return null; 5151 if (query != null) { 5152 if (query.size() >= 1) { 5153 // If there is more than one service with the same priority, 5154 // just arbitrarily pick the first one. 5155 return query.get(0); 5156 } 5157 } 5158 return null; 5159 } 5160 5161 @Override 5162 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 5163 int userId) { 5164 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5165 ComponentName comp = intent.getComponent(); 5166 if (comp == null) { 5167 if (intent.getSelector() != null) { 5168 intent = intent.getSelector(); 5169 comp = intent.getComponent(); 5170 } 5171 } 5172 if (comp != null) { 5173 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5174 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5175 if (si != null) { 5176 final ResolveInfo ri = new ResolveInfo(); 5177 ri.serviceInfo = si; 5178 list.add(ri); 5179 } 5180 return list; 5181 } 5182 5183 // reader 5184 synchronized (mPackages) { 5185 String pkgName = intent.getPackage(); 5186 if (pkgName == null) { 5187 return mServices.queryIntent(intent, resolvedType, flags, userId); 5188 } 5189 final PackageParser.Package pkg = mPackages.get(pkgName); 5190 if (pkg != null) { 5191 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5192 userId); 5193 } 5194 return null; 5195 } 5196 } 5197 5198 @Override 5199 public List<ResolveInfo> queryIntentContentProviders( 5200 Intent intent, String resolvedType, int flags, int userId) { 5201 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5202 ComponentName comp = intent.getComponent(); 5203 if (comp == null) { 5204 if (intent.getSelector() != null) { 5205 intent = intent.getSelector(); 5206 comp = intent.getComponent(); 5207 } 5208 } 5209 if (comp != null) { 5210 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5211 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5212 if (pi != null) { 5213 final ResolveInfo ri = new ResolveInfo(); 5214 ri.providerInfo = pi; 5215 list.add(ri); 5216 } 5217 return list; 5218 } 5219 5220 // reader 5221 synchronized (mPackages) { 5222 String pkgName = intent.getPackage(); 5223 if (pkgName == null) { 5224 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5225 } 5226 final PackageParser.Package pkg = mPackages.get(pkgName); 5227 if (pkg != null) { 5228 return mProviders.queryIntentForPackage( 5229 intent, resolvedType, flags, pkg.providers, userId); 5230 } 5231 return null; 5232 } 5233 } 5234 5235 @Override 5236 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5237 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5238 5239 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 5240 5241 // writer 5242 synchronized (mPackages) { 5243 ArrayList<PackageInfo> list; 5244 if (listUninstalled) { 5245 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5246 for (PackageSetting ps : mSettings.mPackages.values()) { 5247 PackageInfo pi; 5248 if (ps.pkg != null) { 5249 pi = generatePackageInfo(ps.pkg, flags, userId); 5250 } else { 5251 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5252 } 5253 if (pi != null) { 5254 list.add(pi); 5255 } 5256 } 5257 } else { 5258 list = new ArrayList<PackageInfo>(mPackages.size()); 5259 for (PackageParser.Package p : mPackages.values()) { 5260 PackageInfo pi = generatePackageInfo(p, flags, userId); 5261 if (pi != null) { 5262 list.add(pi); 5263 } 5264 } 5265 } 5266 5267 return new ParceledListSlice<PackageInfo>(list); 5268 } 5269 } 5270 5271 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5272 String[] permissions, boolean[] tmp, int flags, int userId) { 5273 int numMatch = 0; 5274 final PermissionsState permissionsState = ps.getPermissionsState(); 5275 for (int i=0; i<permissions.length; i++) { 5276 final String permission = permissions[i]; 5277 if (permissionsState.hasPermission(permission, userId)) { 5278 tmp[i] = true; 5279 numMatch++; 5280 } else { 5281 tmp[i] = false; 5282 } 5283 } 5284 if (numMatch == 0) { 5285 return; 5286 } 5287 PackageInfo pi; 5288 if (ps.pkg != null) { 5289 pi = generatePackageInfo(ps.pkg, flags, userId); 5290 } else { 5291 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5292 } 5293 // The above might return null in cases of uninstalled apps or install-state 5294 // skew across users/profiles. 5295 if (pi != null) { 5296 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5297 if (numMatch == permissions.length) { 5298 pi.requestedPermissions = permissions; 5299 } else { 5300 pi.requestedPermissions = new String[numMatch]; 5301 numMatch = 0; 5302 for (int i=0; i<permissions.length; i++) { 5303 if (tmp[i]) { 5304 pi.requestedPermissions[numMatch] = permissions[i]; 5305 numMatch++; 5306 } 5307 } 5308 } 5309 } 5310 list.add(pi); 5311 } 5312 } 5313 5314 @Override 5315 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5316 String[] permissions, int flags, int userId) { 5317 if (!sUserManager.exists(userId)) return null; 5318 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5319 5320 // writer 5321 synchronized (mPackages) { 5322 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5323 boolean[] tmpBools = new boolean[permissions.length]; 5324 if (listUninstalled) { 5325 for (PackageSetting ps : mSettings.mPackages.values()) { 5326 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5327 } 5328 } else { 5329 for (PackageParser.Package pkg : mPackages.values()) { 5330 PackageSetting ps = (PackageSetting)pkg.mExtras; 5331 if (ps != null) { 5332 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5333 userId); 5334 } 5335 } 5336 } 5337 5338 return new ParceledListSlice<PackageInfo>(list); 5339 } 5340 } 5341 5342 @Override 5343 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 5344 if (!sUserManager.exists(userId)) return null; 5345 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5346 5347 // writer 5348 synchronized (mPackages) { 5349 ArrayList<ApplicationInfo> list; 5350 if (listUninstalled) { 5351 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 5352 for (PackageSetting ps : mSettings.mPackages.values()) { 5353 ApplicationInfo ai; 5354 if (ps.pkg != null) { 5355 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 5356 ps.readUserState(userId), userId); 5357 } else { 5358 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 5359 } 5360 if (ai != null) { 5361 list.add(ai); 5362 } 5363 } 5364 } else { 5365 list = new ArrayList<ApplicationInfo>(mPackages.size()); 5366 for (PackageParser.Package p : mPackages.values()) { 5367 if (p.mExtras != null) { 5368 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5369 ((PackageSetting)p.mExtras).readUserState(userId), userId); 5370 if (ai != null) { 5371 list.add(ai); 5372 } 5373 } 5374 } 5375 } 5376 5377 return new ParceledListSlice<ApplicationInfo>(list); 5378 } 5379 } 5380 5381 public List<ApplicationInfo> getPersistentApplications(int flags) { 5382 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 5383 5384 // reader 5385 synchronized (mPackages) { 5386 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 5387 final int userId = UserHandle.getCallingUserId(); 5388 while (i.hasNext()) { 5389 final PackageParser.Package p = i.next(); 5390 if (p.applicationInfo != null 5391 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 5392 && (!mSafeMode || isSystemApp(p))) { 5393 PackageSetting ps = mSettings.mPackages.get(p.packageName); 5394 if (ps != null) { 5395 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5396 ps.readUserState(userId), userId); 5397 if (ai != null) { 5398 finalList.add(ai); 5399 } 5400 } 5401 } 5402 } 5403 } 5404 5405 return finalList; 5406 } 5407 5408 @Override 5409 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 5410 if (!sUserManager.exists(userId)) return null; 5411 // reader 5412 synchronized (mPackages) { 5413 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 5414 PackageSetting ps = provider != null 5415 ? mSettings.mPackages.get(provider.owner.packageName) 5416 : null; 5417 return ps != null 5418 && mSettings.isEnabledLPr(provider.info, flags, userId) 5419 && (!mSafeMode || (provider.info.applicationInfo.flags 5420 &ApplicationInfo.FLAG_SYSTEM) != 0) 5421 ? PackageParser.generateProviderInfo(provider, flags, 5422 ps.readUserState(userId), userId) 5423 : null; 5424 } 5425 } 5426 5427 /** 5428 * @deprecated 5429 */ 5430 @Deprecated 5431 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 5432 // reader 5433 synchronized (mPackages) { 5434 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 5435 .entrySet().iterator(); 5436 final int userId = UserHandle.getCallingUserId(); 5437 while (i.hasNext()) { 5438 Map.Entry<String, PackageParser.Provider> entry = i.next(); 5439 PackageParser.Provider p = entry.getValue(); 5440 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 5441 5442 if (ps != null && p.syncable 5443 && (!mSafeMode || (p.info.applicationInfo.flags 5444 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 5445 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 5446 ps.readUserState(userId), userId); 5447 if (info != null) { 5448 outNames.add(entry.getKey()); 5449 outInfo.add(info); 5450 } 5451 } 5452 } 5453 } 5454 } 5455 5456 @Override 5457 public ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 5458 int uid, int flags) { 5459 ArrayList<ProviderInfo> finalList = null; 5460 // reader 5461 synchronized (mPackages) { 5462 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 5463 final int userId = processName != null ? 5464 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 5465 while (i.hasNext()) { 5466 final PackageParser.Provider p = i.next(); 5467 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 5468 if (ps != null && p.info.authority != null 5469 && (processName == null 5470 || (p.info.processName.equals(processName) 5471 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 5472 && mSettings.isEnabledLPr(p.info, flags, userId) 5473 && (!mSafeMode 5474 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 5475 if (finalList == null) { 5476 finalList = new ArrayList<ProviderInfo>(3); 5477 } 5478 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 5479 ps.readUserState(userId), userId); 5480 if (info != null) { 5481 finalList.add(info); 5482 } 5483 } 5484 } 5485 } 5486 5487 if (finalList != null) { 5488 Collections.sort(finalList, mProviderInitOrderSorter); 5489 return new ParceledListSlice<ProviderInfo>(finalList); 5490 } 5491 5492 return null; 5493 } 5494 5495 @Override 5496 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 5497 int flags) { 5498 // reader 5499 synchronized (mPackages) { 5500 final PackageParser.Instrumentation i = mInstrumentation.get(name); 5501 return PackageParser.generateInstrumentationInfo(i, flags); 5502 } 5503 } 5504 5505 @Override 5506 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 5507 int flags) { 5508 ArrayList<InstrumentationInfo> finalList = 5509 new ArrayList<InstrumentationInfo>(); 5510 5511 // reader 5512 synchronized (mPackages) { 5513 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 5514 while (i.hasNext()) { 5515 final PackageParser.Instrumentation p = i.next(); 5516 if (targetPackage == null 5517 || targetPackage.equals(p.info.targetPackage)) { 5518 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 5519 flags); 5520 if (ii != null) { 5521 finalList.add(ii); 5522 } 5523 } 5524 } 5525 } 5526 5527 return finalList; 5528 } 5529 5530 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 5531 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 5532 if (overlays == null) { 5533 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 5534 return; 5535 } 5536 for (PackageParser.Package opkg : overlays.values()) { 5537 // Not much to do if idmap fails: we already logged the error 5538 // and we certainly don't want to abort installation of pkg simply 5539 // because an overlay didn't fit properly. For these reasons, 5540 // ignore the return value of createIdmapForPackagePairLI. 5541 createIdmapForPackagePairLI(pkg, opkg); 5542 } 5543 } 5544 5545 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 5546 PackageParser.Package opkg) { 5547 if (!opkg.mTrustedOverlay) { 5548 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 5549 opkg.baseCodePath + ": overlay not trusted"); 5550 return false; 5551 } 5552 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 5553 if (overlaySet == null) { 5554 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 5555 opkg.baseCodePath + " but target package has no known overlays"); 5556 return false; 5557 } 5558 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 5559 // TODO: generate idmap for split APKs 5560 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 5561 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 5562 + opkg.baseCodePath); 5563 return false; 5564 } 5565 PackageParser.Package[] overlayArray = 5566 overlaySet.values().toArray(new PackageParser.Package[0]); 5567 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 5568 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 5569 return p1.mOverlayPriority - p2.mOverlayPriority; 5570 } 5571 }; 5572 Arrays.sort(overlayArray, cmp); 5573 5574 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 5575 int i = 0; 5576 for (PackageParser.Package p : overlayArray) { 5577 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 5578 } 5579 return true; 5580 } 5581 5582 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 5583 final File[] files = dir.listFiles(); 5584 if (ArrayUtils.isEmpty(files)) { 5585 Log.d(TAG, "No files in app dir " + dir); 5586 return; 5587 } 5588 5589 if (DEBUG_PACKAGE_SCANNING) { 5590 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 5591 + " flags=0x" + Integer.toHexString(parseFlags)); 5592 } 5593 5594 for (File file : files) { 5595 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 5596 && !PackageInstallerService.isStageName(file.getName()); 5597 if (!isPackage) { 5598 // Ignore entries which are not packages 5599 continue; 5600 } 5601 try { 5602 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 5603 scanFlags, currentTime, null); 5604 } catch (PackageManagerException e) { 5605 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 5606 5607 // Delete invalid userdata apps 5608 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 5609 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 5610 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 5611 if (file.isDirectory()) { 5612 mInstaller.rmPackageDir(file.getAbsolutePath()); 5613 } else { 5614 file.delete(); 5615 } 5616 } 5617 } 5618 } 5619 } 5620 5621 private static File getSettingsProblemFile() { 5622 File dataDir = Environment.getDataDirectory(); 5623 File systemDir = new File(dataDir, "system"); 5624 File fname = new File(systemDir, "uiderrors.txt"); 5625 return fname; 5626 } 5627 5628 static void reportSettingsProblem(int priority, String msg) { 5629 logCriticalInfo(priority, msg); 5630 } 5631 5632 static void logCriticalInfo(int priority, String msg) { 5633 Slog.println(priority, TAG, msg); 5634 EventLogTags.writePmCriticalInfo(msg); 5635 try { 5636 File fname = getSettingsProblemFile(); 5637 FileOutputStream out = new FileOutputStream(fname, true); 5638 PrintWriter pw = new FastPrintWriter(out); 5639 SimpleDateFormat formatter = new SimpleDateFormat(); 5640 String dateString = formatter.format(new Date(System.currentTimeMillis())); 5641 pw.println(dateString + ": " + msg); 5642 pw.close(); 5643 FileUtils.setPermissions( 5644 fname.toString(), 5645 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 5646 -1, -1); 5647 } catch (java.io.IOException e) { 5648 } 5649 } 5650 5651 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 5652 PackageParser.Package pkg, File srcFile, int parseFlags) 5653 throws PackageManagerException { 5654 if (ps != null 5655 && ps.codePath.equals(srcFile) 5656 && ps.timeStamp == srcFile.lastModified() 5657 && !isCompatSignatureUpdateNeeded(pkg) 5658 && !isRecoverSignatureUpdateNeeded(pkg)) { 5659 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 5660 KeySetManagerService ksms = mSettings.mKeySetManagerService; 5661 ArraySet<PublicKey> signingKs; 5662 synchronized (mPackages) { 5663 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 5664 } 5665 if (ps.signatures.mSignatures != null 5666 && ps.signatures.mSignatures.length != 0 5667 && signingKs != null) { 5668 // Optimization: reuse the existing cached certificates 5669 // if the package appears to be unchanged. 5670 pkg.mSignatures = ps.signatures.mSignatures; 5671 pkg.mSigningKeys = signingKs; 5672 return; 5673 } 5674 5675 Slog.w(TAG, "PackageSetting for " + ps.name 5676 + " is missing signatures. Collecting certs again to recover them."); 5677 } else { 5678 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 5679 } 5680 5681 try { 5682 pp.collectCertificates(pkg, parseFlags); 5683 pp.collectManifestDigest(pkg); 5684 } catch (PackageParserException e) { 5685 throw PackageManagerException.from(e); 5686 } 5687 } 5688 5689 /** 5690 * Traces a package scan. 5691 * @see #scanPackageLI(File, int, int, long, UserHandle) 5692 */ 5693 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 5694 long currentTime, UserHandle user) throws PackageManagerException { 5695 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 5696 try { 5697 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 5698 } finally { 5699 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5700 } 5701 } 5702 5703 /** 5704 * Scans a package and returns the newly parsed package. 5705 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 5706 */ 5707 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 5708 long currentTime, UserHandle user) throws PackageManagerException { 5709 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 5710 parseFlags |= mDefParseFlags; 5711 PackageParser pp = new PackageParser(); 5712 pp.setSeparateProcesses(mSeparateProcesses); 5713 pp.setOnlyCoreApps(mOnlyCore); 5714 pp.setDisplayMetrics(mMetrics); 5715 5716 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 5717 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 5718 } 5719 5720 final PackageParser.Package pkg; 5721 try { 5722 pkg = pp.parsePackage(scanFile, parseFlags); 5723 } catch (PackageParserException e) { 5724 throw PackageManagerException.from(e); 5725 } 5726 5727 PackageSetting ps = null; 5728 PackageSetting updatedPkg; 5729 // reader 5730 synchronized (mPackages) { 5731 // Look to see if we already know about this package. 5732 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 5733 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 5734 // This package has been renamed to its original name. Let's 5735 // use that. 5736 ps = mSettings.peekPackageLPr(oldName); 5737 } 5738 // If there was no original package, see one for the real package name. 5739 if (ps == null) { 5740 ps = mSettings.peekPackageLPr(pkg.packageName); 5741 } 5742 // Check to see if this package could be hiding/updating a system 5743 // package. Must look for it either under the original or real 5744 // package name depending on our state. 5745 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 5746 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 5747 } 5748 boolean updatedPkgBetter = false; 5749 // First check if this is a system package that may involve an update 5750 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5751 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 5752 // it needs to drop FLAG_PRIVILEGED. 5753 if (locationIsPrivileged(scanFile)) { 5754 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5755 } else { 5756 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5757 } 5758 5759 if (ps != null && !ps.codePath.equals(scanFile)) { 5760 // The path has changed from what was last scanned... check the 5761 // version of the new path against what we have stored to determine 5762 // what to do. 5763 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 5764 if (pkg.mVersionCode <= ps.versionCode) { 5765 // The system package has been updated and the code path does not match 5766 // Ignore entry. Skip it. 5767 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 5768 + " ignored: updated version " + ps.versionCode 5769 + " better than this " + pkg.mVersionCode); 5770 if (!updatedPkg.codePath.equals(scanFile)) { 5771 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 5772 + ps.name + " changing from " + updatedPkg.codePathString 5773 + " to " + scanFile); 5774 updatedPkg.codePath = scanFile; 5775 updatedPkg.codePathString = scanFile.toString(); 5776 updatedPkg.resourcePath = scanFile; 5777 updatedPkg.resourcePathString = scanFile.toString(); 5778 } 5779 updatedPkg.pkg = pkg; 5780 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5781 "Package " + ps.name + " at " + scanFile 5782 + " ignored: updated version " + ps.versionCode 5783 + " better than this " + pkg.mVersionCode); 5784 } else { 5785 // The current app on the system partition is better than 5786 // what we have updated to on the data partition; switch 5787 // back to the system partition version. 5788 // At this point, its safely assumed that package installation for 5789 // apps in system partition will go through. If not there won't be a working 5790 // version of the app 5791 // writer 5792 synchronized (mPackages) { 5793 // Just remove the loaded entries from package lists. 5794 mPackages.remove(ps.name); 5795 } 5796 5797 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5798 + " reverting from " + ps.codePathString 5799 + ": new version " + pkg.mVersionCode 5800 + " better than installed " + ps.versionCode); 5801 5802 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5803 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5804 synchronized (mInstallLock) { 5805 args.cleanUpResourcesLI(); 5806 } 5807 synchronized (mPackages) { 5808 mSettings.enableSystemPackageLPw(ps.name); 5809 } 5810 updatedPkgBetter = true; 5811 } 5812 } 5813 } 5814 5815 if (updatedPkg != null) { 5816 // An updated system app will not have the PARSE_IS_SYSTEM flag set 5817 // initially 5818 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 5819 5820 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 5821 // flag set initially 5822 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 5823 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 5824 } 5825 } 5826 5827 // Verify certificates against what was last scanned 5828 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 5829 5830 /* 5831 * A new system app appeared, but we already had a non-system one of the 5832 * same name installed earlier. 5833 */ 5834 boolean shouldHideSystemApp = false; 5835 if (updatedPkg == null && ps != null 5836 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 5837 /* 5838 * Check to make sure the signatures match first. If they don't, 5839 * wipe the installed application and its data. 5840 */ 5841 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 5842 != PackageManager.SIGNATURE_MATCH) { 5843 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 5844 + " signatures don't match existing userdata copy; removing"); 5845 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 5846 ps = null; 5847 } else { 5848 /* 5849 * If the newly-added system app is an older version than the 5850 * already installed version, hide it. It will be scanned later 5851 * and re-added like an update. 5852 */ 5853 if (pkg.mVersionCode <= ps.versionCode) { 5854 shouldHideSystemApp = true; 5855 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 5856 + " but new version " + pkg.mVersionCode + " better than installed " 5857 + ps.versionCode + "; hiding system"); 5858 } else { 5859 /* 5860 * The newly found system app is a newer version that the 5861 * one previously installed. Simply remove the 5862 * already-installed application and replace it with our own 5863 * while keeping the application data. 5864 */ 5865 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5866 + " reverting from " + ps.codePathString + ": new version " 5867 + pkg.mVersionCode + " better than installed " + ps.versionCode); 5868 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5869 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5870 synchronized (mInstallLock) { 5871 args.cleanUpResourcesLI(); 5872 } 5873 } 5874 } 5875 } 5876 5877 // The apk is forward locked (not public) if its code and resources 5878 // are kept in different files. (except for app in either system or 5879 // vendor path). 5880 // TODO grab this value from PackageSettings 5881 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5882 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 5883 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 5884 } 5885 } 5886 5887 // TODO: extend to support forward-locked splits 5888 String resourcePath = null; 5889 String baseResourcePath = null; 5890 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 5891 if (ps != null && ps.resourcePathString != null) { 5892 resourcePath = ps.resourcePathString; 5893 baseResourcePath = ps.resourcePathString; 5894 } else { 5895 // Should not happen at all. Just log an error. 5896 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 5897 } 5898 } else { 5899 resourcePath = pkg.codePath; 5900 baseResourcePath = pkg.baseCodePath; 5901 } 5902 5903 // Set application objects path explicitly. 5904 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 5905 pkg.applicationInfo.setCodePath(pkg.codePath); 5906 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 5907 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 5908 pkg.applicationInfo.setResourcePath(resourcePath); 5909 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 5910 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 5911 5912 // Note that we invoke the following method only if we are about to unpack an application 5913 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 5914 | SCAN_UPDATE_SIGNATURE, currentTime, user); 5915 5916 /* 5917 * If the system app should be overridden by a previously installed 5918 * data, hide the system app now and let the /data/app scan pick it up 5919 * again. 5920 */ 5921 if (shouldHideSystemApp) { 5922 synchronized (mPackages) { 5923 /* 5924 * We have to grant systems permissions before we hide, because 5925 * grantPermissions will assume the package update is trying to 5926 * expand its permissions. 5927 */ 5928 grantPermissionsLPw(pkg, true, pkg.packageName); 5929 mSettings.disableSystemPackageLPw(pkg.packageName); 5930 } 5931 } 5932 5933 return scannedPkg; 5934 } 5935 5936 private static String fixProcessName(String defProcessName, 5937 String processName, int uid) { 5938 if (processName == null) { 5939 return defProcessName; 5940 } 5941 return processName; 5942 } 5943 5944 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 5945 throws PackageManagerException { 5946 if (pkgSetting.signatures.mSignatures != null) { 5947 // Already existing package. Make sure signatures match 5948 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 5949 == PackageManager.SIGNATURE_MATCH; 5950 if (!match) { 5951 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 5952 == PackageManager.SIGNATURE_MATCH; 5953 } 5954 if (!match) { 5955 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 5956 == PackageManager.SIGNATURE_MATCH; 5957 } 5958 if (!match) { 5959 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5960 + pkg.packageName + " signatures do not match the " 5961 + "previously installed version; ignoring!"); 5962 } 5963 } 5964 5965 // Check for shared user signatures 5966 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 5967 // Already existing package. Make sure signatures match 5968 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5969 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 5970 if (!match) { 5971 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 5972 == PackageManager.SIGNATURE_MATCH; 5973 } 5974 if (!match) { 5975 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 5976 == PackageManager.SIGNATURE_MATCH; 5977 } 5978 if (!match) { 5979 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 5980 "Package " + pkg.packageName 5981 + " has no signatures that match those in shared user " 5982 + pkgSetting.sharedUser.name + "; ignoring!"); 5983 } 5984 } 5985 } 5986 5987 /** 5988 * Enforces that only the system UID or root's UID can call a method exposed 5989 * via Binder. 5990 * 5991 * @param message used as message if SecurityException is thrown 5992 * @throws SecurityException if the caller is not system or root 5993 */ 5994 private static final void enforceSystemOrRoot(String message) { 5995 final int uid = Binder.getCallingUid(); 5996 if (uid != Process.SYSTEM_UID && uid != 0) { 5997 throw new SecurityException(message); 5998 } 5999 } 6000 6001 @Override 6002 public void performBootDexOpt() { 6003 enforceSystemOrRoot("Only the system can request dexopt be performed"); 6004 6005 // Before everything else, see whether we need to fstrim. 6006 try { 6007 IMountService ms = PackageHelper.getMountService(); 6008 if (ms != null) { 6009 final boolean isUpgrade = isUpgrade(); 6010 boolean doTrim = isUpgrade; 6011 if (doTrim) { 6012 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6013 } else { 6014 final long interval = android.provider.Settings.Global.getLong( 6015 mContext.getContentResolver(), 6016 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6017 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6018 if (interval > 0) { 6019 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6020 if (timeSinceLast > interval) { 6021 doTrim = true; 6022 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6023 + "; running immediately"); 6024 } 6025 } 6026 } 6027 if (doTrim) { 6028 if (!isFirstBoot()) { 6029 try { 6030 ActivityManagerNative.getDefault().showBootMessage( 6031 mContext.getResources().getString( 6032 R.string.android_upgrading_fstrim), true); 6033 } catch (RemoteException e) { 6034 } 6035 } 6036 ms.runMaintenance(); 6037 } 6038 } else { 6039 Slog.e(TAG, "Mount service unavailable!"); 6040 } 6041 } catch (RemoteException e) { 6042 // Can't happen; MountService is local 6043 } 6044 6045 final ArraySet<PackageParser.Package> pkgs; 6046 synchronized (mPackages) { 6047 pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages(); 6048 } 6049 6050 if (pkgs != null) { 6051 // Sort apps by importance for dexopt ordering. Important apps are given more priority 6052 // in case the device runs out of space. 6053 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 6054 // Give priority to core apps. 6055 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6056 PackageParser.Package pkg = it.next(); 6057 if (pkg.coreApp) { 6058 if (DEBUG_DEXOPT) { 6059 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 6060 } 6061 sortedPkgs.add(pkg); 6062 it.remove(); 6063 } 6064 } 6065 // Give priority to system apps that listen for pre boot complete. 6066 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 6067 ArraySet<String> pkgNames = getPackageNamesForIntent(intent); 6068 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6069 PackageParser.Package pkg = it.next(); 6070 if (pkgNames.contains(pkg.packageName)) { 6071 if (DEBUG_DEXOPT) { 6072 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 6073 } 6074 sortedPkgs.add(pkg); 6075 it.remove(); 6076 } 6077 } 6078 // Give priority to system apps. 6079 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6080 PackageParser.Package pkg = it.next(); 6081 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 6082 if (DEBUG_DEXOPT) { 6083 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName); 6084 } 6085 sortedPkgs.add(pkg); 6086 it.remove(); 6087 } 6088 } 6089 // Give priority to updated system apps. 6090 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6091 PackageParser.Package pkg = it.next(); 6092 if (pkg.isUpdatedSystemApp()) { 6093 if (DEBUG_DEXOPT) { 6094 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName); 6095 } 6096 sortedPkgs.add(pkg); 6097 it.remove(); 6098 } 6099 } 6100 // Give priority to apps that listen for boot complete. 6101 intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 6102 pkgNames = getPackageNamesForIntent(intent); 6103 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6104 PackageParser.Package pkg = it.next(); 6105 if (pkgNames.contains(pkg.packageName)) { 6106 if (DEBUG_DEXOPT) { 6107 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName); 6108 } 6109 sortedPkgs.add(pkg); 6110 it.remove(); 6111 } 6112 } 6113 // Filter out packages that aren't recently used. 6114 filterRecentlyUsedApps(pkgs); 6115 // Add all remaining apps. 6116 for (PackageParser.Package pkg : pkgs) { 6117 if (DEBUG_DEXOPT) { 6118 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 6119 } 6120 sortedPkgs.add(pkg); 6121 } 6122 6123 // If we want to be lazy, filter everything that wasn't recently used. 6124 if (mLazyDexOpt) { 6125 filterRecentlyUsedApps(sortedPkgs); 6126 } 6127 6128 int i = 0; 6129 int total = sortedPkgs.size(); 6130 File dataDir = Environment.getDataDirectory(); 6131 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 6132 if (lowThreshold == 0) { 6133 throw new IllegalStateException("Invalid low memory threshold"); 6134 } 6135 for (PackageParser.Package pkg : sortedPkgs) { 6136 long usableSpace = dataDir.getUsableSpace(); 6137 if (usableSpace < lowThreshold) { 6138 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 6139 break; 6140 } 6141 performBootDexOpt(pkg, ++i, total); 6142 } 6143 } 6144 } 6145 6146 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 6147 // Filter out packages that aren't recently used. 6148 // 6149 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 6150 // should do a full dexopt. 6151 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 6152 int total = pkgs.size(); 6153 int skipped = 0; 6154 long now = System.currentTimeMillis(); 6155 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 6156 PackageParser.Package pkg = i.next(); 6157 long then = pkg.mLastPackageUsageTimeInMills; 6158 if (then + mDexOptLRUThresholdInMills < now) { 6159 if (DEBUG_DEXOPT) { 6160 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 6161 ((then == 0) ? "never" : new Date(then))); 6162 } 6163 i.remove(); 6164 skipped++; 6165 } 6166 } 6167 if (DEBUG_DEXOPT) { 6168 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 6169 } 6170 } 6171 } 6172 6173 private ArraySet<String> getPackageNamesForIntent(Intent intent) { 6174 List<ResolveInfo> ris = null; 6175 try { 6176 ris = AppGlobals.getPackageManager().queryIntentReceivers( 6177 intent, null, 0, UserHandle.USER_OWNER); 6178 } catch (RemoteException e) { 6179 } 6180 ArraySet<String> pkgNames = new ArraySet<String>(); 6181 if (ris != null) { 6182 for (ResolveInfo ri : ris) { 6183 pkgNames.add(ri.activityInfo.packageName); 6184 } 6185 } 6186 return pkgNames; 6187 } 6188 6189 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 6190 if (DEBUG_DEXOPT) { 6191 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 6192 } 6193 if (!isFirstBoot()) { 6194 try { 6195 ActivityManagerNative.getDefault().showBootMessage( 6196 mContext.getResources().getString(R.string.android_upgrading_apk, 6197 curr, total), true); 6198 } catch (RemoteException e) { 6199 } 6200 } 6201 PackageParser.Package p = pkg; 6202 synchronized (mInstallLock) { 6203 mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, 6204 false /* force dex */, false /* defer */, true /* include dependencies */); 6205 } 6206 } 6207 6208 @Override 6209 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6210 return performDexOpt(packageName, instructionSet, false); 6211 } 6212 6213 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) { 6214 boolean dexopt = mLazyDexOpt || backgroundDexopt; 6215 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 6216 if (!dexopt && !updateUsage) { 6217 // We aren't going to dexopt or update usage, so bail early. 6218 return false; 6219 } 6220 PackageParser.Package p; 6221 final String targetInstructionSet; 6222 synchronized (mPackages) { 6223 p = mPackages.get(packageName); 6224 if (p == null) { 6225 return false; 6226 } 6227 if (updateUsage) { 6228 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6229 } 6230 mPackageUsage.write(false); 6231 if (!dexopt) { 6232 // We aren't going to dexopt, so bail early. 6233 return false; 6234 } 6235 6236 targetInstructionSet = instructionSet != null ? instructionSet : 6237 getPrimaryInstructionSet(p.applicationInfo); 6238 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 6239 return false; 6240 } 6241 } 6242 long callingId = Binder.clearCallingIdentity(); 6243 try { 6244 synchronized (mInstallLock) { 6245 final String[] instructionSets = new String[] { targetInstructionSet }; 6246 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, 6247 false /* forceDex */, false /* defer */, true /* inclDependencies */); 6248 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 6249 } 6250 } finally { 6251 Binder.restoreCallingIdentity(callingId); 6252 } 6253 } 6254 6255 public ArraySet<String> getPackagesThatNeedDexOpt() { 6256 ArraySet<String> pkgs = null; 6257 synchronized (mPackages) { 6258 for (PackageParser.Package p : mPackages.values()) { 6259 if (DEBUG_DEXOPT) { 6260 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 6261 } 6262 if (!p.mDexOptPerformed.isEmpty()) { 6263 continue; 6264 } 6265 if (pkgs == null) { 6266 pkgs = new ArraySet<String>(); 6267 } 6268 pkgs.add(p.packageName); 6269 } 6270 } 6271 return pkgs; 6272 } 6273 6274 public void shutdown() { 6275 mPackageUsage.write(true); 6276 } 6277 6278 @Override 6279 public void forceDexOpt(String packageName) { 6280 enforceSystemOrRoot("forceDexOpt"); 6281 6282 PackageParser.Package pkg; 6283 synchronized (mPackages) { 6284 pkg = mPackages.get(packageName); 6285 if (pkg == null) { 6286 throw new IllegalArgumentException("Missing package: " + packageName); 6287 } 6288 } 6289 6290 synchronized (mInstallLock) { 6291 final String[] instructionSets = new String[] { 6292 getPrimaryInstructionSet(pkg.applicationInfo) }; 6293 final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, 6294 true /*forceDex*/, false /* defer */, true /* inclDependencies */); 6295 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 6296 throw new IllegalStateException("Failed to dexopt: " + res); 6297 } 6298 } 6299 } 6300 6301 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 6302 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6303 Slog.w(TAG, "Unable to update from " + oldPkg.name 6304 + " to " + newPkg.packageName 6305 + ": old package not in system partition"); 6306 return false; 6307 } else if (mPackages.get(oldPkg.name) != null) { 6308 Slog.w(TAG, "Unable to update from " + oldPkg.name 6309 + " to " + newPkg.packageName 6310 + ": old package still exists"); 6311 return false; 6312 } 6313 return true; 6314 } 6315 6316 private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) { 6317 int[] users = sUserManager.getUserIds(); 6318 int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo); 6319 if (res < 0) { 6320 return res; 6321 } 6322 for (int user : users) { 6323 if (user != 0) { 6324 res = mInstaller.createUserData(volumeUuid, packageName, 6325 UserHandle.getUid(user, uid), user, seinfo); 6326 if (res < 0) { 6327 return res; 6328 } 6329 } 6330 } 6331 return res; 6332 } 6333 6334 private int removeDataDirsLI(String volumeUuid, String packageName) { 6335 int[] users = sUserManager.getUserIds(); 6336 int res = 0; 6337 for (int user : users) { 6338 int resInner = mInstaller.remove(volumeUuid, packageName, user); 6339 if (resInner < 0) { 6340 res = resInner; 6341 } 6342 } 6343 6344 return res; 6345 } 6346 6347 private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 6348 int[] users = sUserManager.getUserIds(); 6349 int res = 0; 6350 for (int user : users) { 6351 int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user); 6352 if (resInner < 0) { 6353 res = resInner; 6354 } 6355 } 6356 return res; 6357 } 6358 6359 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 6360 PackageParser.Package changingLib) { 6361 if (file.path != null) { 6362 usesLibraryFiles.add(file.path); 6363 return; 6364 } 6365 PackageParser.Package p = mPackages.get(file.apk); 6366 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 6367 // If we are doing this while in the middle of updating a library apk, 6368 // then we need to make sure to use that new apk for determining the 6369 // dependencies here. (We haven't yet finished committing the new apk 6370 // to the package manager state.) 6371 if (p == null || p.packageName.equals(changingLib.packageName)) { 6372 p = changingLib; 6373 } 6374 } 6375 if (p != null) { 6376 usesLibraryFiles.addAll(p.getAllCodePaths()); 6377 } 6378 } 6379 6380 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 6381 PackageParser.Package changingLib) throws PackageManagerException { 6382 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 6383 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 6384 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 6385 for (int i=0; i<N; i++) { 6386 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 6387 if (file == null) { 6388 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 6389 "Package " + pkg.packageName + " requires unavailable shared library " 6390 + pkg.usesLibraries.get(i) + "; failing!"); 6391 } 6392 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 6393 } 6394 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 6395 for (int i=0; i<N; i++) { 6396 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 6397 if (file == null) { 6398 Slog.w(TAG, "Package " + pkg.packageName 6399 + " desires unavailable shared library " 6400 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 6401 } else { 6402 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 6403 } 6404 } 6405 N = usesLibraryFiles.size(); 6406 if (N > 0) { 6407 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 6408 } else { 6409 pkg.usesLibraryFiles = null; 6410 } 6411 } 6412 } 6413 6414 private static boolean hasString(List<String> list, List<String> which) { 6415 if (list == null) { 6416 return false; 6417 } 6418 for (int i=list.size()-1; i>=0; i--) { 6419 for (int j=which.size()-1; j>=0; j--) { 6420 if (which.get(j).equals(list.get(i))) { 6421 return true; 6422 } 6423 } 6424 } 6425 return false; 6426 } 6427 6428 private void updateAllSharedLibrariesLPw() { 6429 for (PackageParser.Package pkg : mPackages.values()) { 6430 try { 6431 updateSharedLibrariesLPw(pkg, null); 6432 } catch (PackageManagerException e) { 6433 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 6434 } 6435 } 6436 } 6437 6438 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 6439 PackageParser.Package changingPkg) { 6440 ArrayList<PackageParser.Package> res = null; 6441 for (PackageParser.Package pkg : mPackages.values()) { 6442 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 6443 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 6444 if (res == null) { 6445 res = new ArrayList<PackageParser.Package>(); 6446 } 6447 res.add(pkg); 6448 try { 6449 updateSharedLibrariesLPw(pkg, changingPkg); 6450 } catch (PackageManagerException e) { 6451 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 6452 } 6453 } 6454 } 6455 return res; 6456 } 6457 6458 /** 6459 * Derive the value of the {@code cpuAbiOverride} based on the provided 6460 * value and an optional stored value from the package settings. 6461 */ 6462 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 6463 String cpuAbiOverride = null; 6464 6465 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 6466 cpuAbiOverride = null; 6467 } else if (abiOverride != null) { 6468 cpuAbiOverride = abiOverride; 6469 } else if (settings != null) { 6470 cpuAbiOverride = settings.cpuAbiOverrideString; 6471 } 6472 6473 return cpuAbiOverride; 6474 } 6475 6476 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 6477 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6478 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6479 try { 6480 return scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 6481 } finally { 6482 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6483 } 6484 } 6485 6486 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 6487 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6488 boolean success = false; 6489 try { 6490 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 6491 currentTime, user); 6492 success = true; 6493 return res; 6494 } finally { 6495 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 6496 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 6497 } 6498 } 6499 } 6500 6501 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 6502 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6503 final File scanFile = new File(pkg.codePath); 6504 if (pkg.applicationInfo.getCodePath() == null || 6505 pkg.applicationInfo.getResourcePath() == null) { 6506 // Bail out. The resource and code paths haven't been set. 6507 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 6508 "Code and resource paths haven't been set correctly"); 6509 } 6510 6511 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 6512 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 6513 } else { 6514 // Only allow system apps to be flagged as core apps. 6515 pkg.coreApp = false; 6516 } 6517 6518 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 6519 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6520 } 6521 6522 if (mCustomResolverComponentName != null && 6523 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 6524 setUpCustomResolverActivity(pkg); 6525 } 6526 6527 if (pkg.packageName.equals("android")) { 6528 synchronized (mPackages) { 6529 if (mAndroidApplication != null) { 6530 Slog.w(TAG, "*************************************************"); 6531 Slog.w(TAG, "Core android package being redefined. Skipping."); 6532 Slog.w(TAG, " file=" + scanFile); 6533 Slog.w(TAG, "*************************************************"); 6534 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 6535 "Core android package being redefined. Skipping."); 6536 } 6537 6538 // Set up information for our fall-back user intent resolution activity. 6539 mPlatformPackage = pkg; 6540 pkg.mVersionCode = mSdkVersion; 6541 mAndroidApplication = pkg.applicationInfo; 6542 6543 if (!mResolverReplaced) { 6544 mResolveActivity.applicationInfo = mAndroidApplication; 6545 mResolveActivity.name = ResolverActivity.class.getName(); 6546 mResolveActivity.packageName = mAndroidApplication.packageName; 6547 mResolveActivity.processName = "system:ui"; 6548 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6549 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 6550 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 6551 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 6552 mResolveActivity.exported = true; 6553 mResolveActivity.enabled = true; 6554 mResolveInfo.activityInfo = mResolveActivity; 6555 mResolveInfo.priority = 0; 6556 mResolveInfo.preferredOrder = 0; 6557 mResolveInfo.match = 0; 6558 mResolveComponentName = new ComponentName( 6559 mAndroidApplication.packageName, mResolveActivity.name); 6560 } 6561 } 6562 } 6563 6564 if (DEBUG_PACKAGE_SCANNING) { 6565 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6566 Log.d(TAG, "Scanning package " + pkg.packageName); 6567 } 6568 6569 if (mPackages.containsKey(pkg.packageName) 6570 || mSharedLibraries.containsKey(pkg.packageName)) { 6571 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 6572 "Application package " + pkg.packageName 6573 + " already installed. Skipping duplicate."); 6574 } 6575 6576 // If we're only installing presumed-existing packages, require that the 6577 // scanned APK is both already known and at the path previously established 6578 // for it. Previously unknown packages we pick up normally, but if we have an 6579 // a priori expectation about this package's install presence, enforce it. 6580 // With a singular exception for new system packages. When an OTA contains 6581 // a new system package, we allow the codepath to change from a system location 6582 // to the user-installed location. If we don't allow this change, any newer, 6583 // user-installed version of the application will be ignored. 6584 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 6585 if (mExpectingBetter.containsKey(pkg.packageName)) { 6586 logCriticalInfo(Log.WARN, 6587 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 6588 } else { 6589 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 6590 if (known != null) { 6591 if (DEBUG_PACKAGE_SCANNING) { 6592 Log.d(TAG, "Examining " + pkg.codePath 6593 + " and requiring known paths " + known.codePathString 6594 + " & " + known.resourcePathString); 6595 } 6596 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 6597 || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { 6598 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 6599 "Application package " + pkg.packageName 6600 + " found at " + pkg.applicationInfo.getCodePath() 6601 + " but expected at " + known.codePathString + "; ignoring."); 6602 } 6603 } 6604 } 6605 } 6606 6607 // Initialize package source and resource directories 6608 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 6609 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 6610 6611 SharedUserSetting suid = null; 6612 PackageSetting pkgSetting = null; 6613 6614 if (!isSystemApp(pkg)) { 6615 // Only system apps can use these features. 6616 pkg.mOriginalPackages = null; 6617 pkg.mRealPackage = null; 6618 pkg.mAdoptPermissions = null; 6619 } 6620 6621 // writer 6622 synchronized (mPackages) { 6623 if (pkg.mSharedUserId != null) { 6624 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 6625 if (suid == null) { 6626 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6627 "Creating application package " + pkg.packageName 6628 + " for shared user failed"); 6629 } 6630 if (DEBUG_PACKAGE_SCANNING) { 6631 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6632 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 6633 + "): packages=" + suid.packages); 6634 } 6635 } 6636 6637 // Check if we are renaming from an original package name. 6638 PackageSetting origPackage = null; 6639 String realName = null; 6640 if (pkg.mOriginalPackages != null) { 6641 // This package may need to be renamed to a previously 6642 // installed name. Let's check on that... 6643 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 6644 if (pkg.mOriginalPackages.contains(renamed)) { 6645 // This package had originally been installed as the 6646 // original name, and we have already taken care of 6647 // transitioning to the new one. Just update the new 6648 // one to continue using the old name. 6649 realName = pkg.mRealPackage; 6650 if (!pkg.packageName.equals(renamed)) { 6651 // Callers into this function may have already taken 6652 // care of renaming the package; only do it here if 6653 // it is not already done. 6654 pkg.setPackageName(renamed); 6655 } 6656 6657 } else { 6658 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 6659 if ((origPackage = mSettings.peekPackageLPr( 6660 pkg.mOriginalPackages.get(i))) != null) { 6661 // We do have the package already installed under its 6662 // original name... should we use it? 6663 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 6664 // New package is not compatible with original. 6665 origPackage = null; 6666 continue; 6667 } else if (origPackage.sharedUser != null) { 6668 // Make sure uid is compatible between packages. 6669 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 6670 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 6671 + " to " + pkg.packageName + ": old uid " 6672 + origPackage.sharedUser.name 6673 + " differs from " + pkg.mSharedUserId); 6674 origPackage = null; 6675 continue; 6676 } 6677 } else { 6678 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 6679 + pkg.packageName + " to old name " + origPackage.name); 6680 } 6681 break; 6682 } 6683 } 6684 } 6685 } 6686 6687 if (mTransferedPackages.contains(pkg.packageName)) { 6688 Slog.w(TAG, "Package " + pkg.packageName 6689 + " was transferred to another, but its .apk remains"); 6690 } 6691 6692 // Just create the setting, don't add it yet. For already existing packages 6693 // the PkgSetting exists already and doesn't have to be created. 6694 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 6695 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 6696 pkg.applicationInfo.primaryCpuAbi, 6697 pkg.applicationInfo.secondaryCpuAbi, 6698 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 6699 user, false); 6700 if (pkgSetting == null) { 6701 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6702 "Creating application package " + pkg.packageName + " failed"); 6703 } 6704 6705 if (pkgSetting.origPackage != null) { 6706 // If we are first transitioning from an original package, 6707 // fix up the new package's name now. We need to do this after 6708 // looking up the package under its new name, so getPackageLP 6709 // can take care of fiddling things correctly. 6710 pkg.setPackageName(origPackage.name); 6711 6712 // File a report about this. 6713 String msg = "New package " + pkgSetting.realName 6714 + " renamed to replace old package " + pkgSetting.name; 6715 reportSettingsProblem(Log.WARN, msg); 6716 6717 // Make a note of it. 6718 mTransferedPackages.add(origPackage.name); 6719 6720 // No longer need to retain this. 6721 pkgSetting.origPackage = null; 6722 } 6723 6724 if (realName != null) { 6725 // Make a note of it. 6726 mTransferedPackages.add(pkg.packageName); 6727 } 6728 6729 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 6730 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 6731 } 6732 6733 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6734 // Check all shared libraries and map to their actual file path. 6735 // We only do this here for apps not on a system dir, because those 6736 // are the only ones that can fail an install due to this. We 6737 // will take care of the system apps by updating all of their 6738 // library paths after the scan is done. 6739 updateSharedLibrariesLPw(pkg, null); 6740 } 6741 6742 if (mFoundPolicyFile) { 6743 SELinuxMMAC.assignSeinfoValue(pkg); 6744 } 6745 6746 pkg.applicationInfo.uid = pkgSetting.appId; 6747 pkg.mExtras = pkgSetting; 6748 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 6749 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 6750 // We just determined the app is signed correctly, so bring 6751 // over the latest parsed certs. 6752 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6753 } else { 6754 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6755 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6756 "Package " + pkg.packageName + " upgrade keys do not match the " 6757 + "previously installed version"); 6758 } else { 6759 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6760 String msg = "System package " + pkg.packageName 6761 + " signature changed; retaining data."; 6762 reportSettingsProblem(Log.WARN, msg); 6763 } 6764 } 6765 } else { 6766 try { 6767 verifySignaturesLP(pkgSetting, pkg); 6768 // We just determined the app is signed correctly, so bring 6769 // over the latest parsed certs. 6770 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6771 } catch (PackageManagerException e) { 6772 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6773 throw e; 6774 } 6775 // The signature has changed, but this package is in the system 6776 // image... let's recover! 6777 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6778 // However... if this package is part of a shared user, but it 6779 // doesn't match the signature of the shared user, let's fail. 6780 // What this means is that you can't change the signatures 6781 // associated with an overall shared user, which doesn't seem all 6782 // that unreasonable. 6783 if (pkgSetting.sharedUser != null) { 6784 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6785 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 6786 throw new PackageManagerException( 6787 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 6788 "Signature mismatch for shared user : " 6789 + pkgSetting.sharedUser); 6790 } 6791 } 6792 // File a report about this. 6793 String msg = "System package " + pkg.packageName 6794 + " signature changed; retaining data."; 6795 reportSettingsProblem(Log.WARN, msg); 6796 } 6797 } 6798 // Verify that this new package doesn't have any content providers 6799 // that conflict with existing packages. Only do this if the 6800 // package isn't already installed, since we don't want to break 6801 // things that are installed. 6802 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 6803 final int N = pkg.providers.size(); 6804 int i; 6805 for (i=0; i<N; i++) { 6806 PackageParser.Provider p = pkg.providers.get(i); 6807 if (p.info.authority != null) { 6808 String names[] = p.info.authority.split(";"); 6809 for (int j = 0; j < names.length; j++) { 6810 if (mProvidersByAuthority.containsKey(names[j])) { 6811 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6812 final String otherPackageName = 6813 ((other != null && other.getComponentName() != null) ? 6814 other.getComponentName().getPackageName() : "?"); 6815 throw new PackageManagerException( 6816 INSTALL_FAILED_CONFLICTING_PROVIDER, 6817 "Can't install because provider name " + names[j] 6818 + " (in package " + pkg.applicationInfo.packageName 6819 + ") is already used by " + otherPackageName); 6820 } 6821 } 6822 } 6823 } 6824 } 6825 6826 if (pkg.mAdoptPermissions != null) { 6827 // This package wants to adopt ownership of permissions from 6828 // another package. 6829 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 6830 final String origName = pkg.mAdoptPermissions.get(i); 6831 final PackageSetting orig = mSettings.peekPackageLPr(origName); 6832 if (orig != null) { 6833 if (verifyPackageUpdateLPr(orig, pkg)) { 6834 Slog.i(TAG, "Adopting permissions from " + origName + " to " 6835 + pkg.packageName); 6836 mSettings.transferPermissionsLPw(origName, pkg.packageName); 6837 } 6838 } 6839 } 6840 } 6841 } 6842 6843 final String pkgName = pkg.packageName; 6844 6845 final long scanFileTime = scanFile.lastModified(); 6846 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 6847 pkg.applicationInfo.processName = fixProcessName( 6848 pkg.applicationInfo.packageName, 6849 pkg.applicationInfo.processName, 6850 pkg.applicationInfo.uid); 6851 6852 File dataPath; 6853 if (mPlatformPackage == pkg) { 6854 // The system package is special. 6855 dataPath = new File(Environment.getDataDirectory(), "system"); 6856 6857 pkg.applicationInfo.dataDir = dataPath.getPath(); 6858 6859 } else { 6860 // This is a normal package, need to make its data directory. 6861 dataPath = Environment.getDataUserPackageDirectory(pkg.volumeUuid, 6862 UserHandle.USER_OWNER, pkg.packageName); 6863 6864 boolean uidError = false; 6865 if (dataPath.exists()) { 6866 int currentUid = 0; 6867 try { 6868 StructStat stat = Os.stat(dataPath.getPath()); 6869 currentUid = stat.st_uid; 6870 } catch (ErrnoException e) { 6871 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 6872 } 6873 6874 // If we have mismatched owners for the data path, we have a problem. 6875 if (currentUid != pkg.applicationInfo.uid) { 6876 boolean recovered = false; 6877 if (currentUid == 0) { 6878 // The directory somehow became owned by root. Wow. 6879 // This is probably because the system was stopped while 6880 // installd was in the middle of messing with its libs 6881 // directory. Ask installd to fix that. 6882 int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName, 6883 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 6884 if (ret >= 0) { 6885 recovered = true; 6886 String msg = "Package " + pkg.packageName 6887 + " unexpectedly changed to uid 0; recovered to " + 6888 + pkg.applicationInfo.uid; 6889 reportSettingsProblem(Log.WARN, msg); 6890 } 6891 } 6892 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6893 || (scanFlags&SCAN_BOOTING) != 0)) { 6894 // If this is a system app, we can at least delete its 6895 // current data so the application will still work. 6896 int ret = removeDataDirsLI(pkg.volumeUuid, pkgName); 6897 if (ret >= 0) { 6898 // TODO: Kill the processes first 6899 // Old data gone! 6900 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6901 ? "System package " : "Third party package "; 6902 String msg = prefix + pkg.packageName 6903 + " has changed from uid: " 6904 + currentUid + " to " 6905 + pkg.applicationInfo.uid + "; old data erased"; 6906 reportSettingsProblem(Log.WARN, msg); 6907 recovered = true; 6908 6909 // And now re-install the app. 6910 ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6911 pkg.applicationInfo.seinfo); 6912 if (ret == -1) { 6913 // Ack should not happen! 6914 msg = prefix + pkg.packageName 6915 + " could not have data directory re-created after delete."; 6916 reportSettingsProblem(Log.WARN, msg); 6917 throw new PackageManagerException( 6918 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 6919 } 6920 } 6921 if (!recovered) { 6922 mHasSystemUidErrors = true; 6923 } 6924 } else if (!recovered) { 6925 // If we allow this install to proceed, we will be broken. 6926 // Abort, abort! 6927 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 6928 "scanPackageLI"); 6929 } 6930 if (!recovered) { 6931 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 6932 + pkg.applicationInfo.uid + "/fs_" 6933 + currentUid; 6934 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 6935 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 6936 String msg = "Package " + pkg.packageName 6937 + " has mismatched uid: " 6938 + currentUid + " on disk, " 6939 + pkg.applicationInfo.uid + " in settings"; 6940 // writer 6941 synchronized (mPackages) { 6942 mSettings.mReadMessages.append(msg); 6943 mSettings.mReadMessages.append('\n'); 6944 uidError = true; 6945 if (!pkgSetting.uidError) { 6946 reportSettingsProblem(Log.ERROR, msg); 6947 } 6948 } 6949 } 6950 } 6951 pkg.applicationInfo.dataDir = dataPath.getPath(); 6952 if (mShouldRestoreconData) { 6953 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 6954 mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName, 6955 pkg.applicationInfo.seinfo, pkg.applicationInfo.uid); 6956 } 6957 } else { 6958 if (DEBUG_PACKAGE_SCANNING) { 6959 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6960 Log.v(TAG, "Want this data dir: " + dataPath); 6961 } 6962 //invoke installer to do the actual installation 6963 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6964 pkg.applicationInfo.seinfo); 6965 if (ret < 0) { 6966 // Error from installer 6967 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6968 "Unable to create data dirs [errorCode=" + ret + "]"); 6969 } 6970 6971 if (dataPath.exists()) { 6972 pkg.applicationInfo.dataDir = dataPath.getPath(); 6973 } else { 6974 Slog.w(TAG, "Unable to create data directory: " + dataPath); 6975 pkg.applicationInfo.dataDir = null; 6976 } 6977 } 6978 6979 pkgSetting.uidError = uidError; 6980 } 6981 6982 final String path = scanFile.getPath(); 6983 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 6984 6985 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 6986 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 6987 6988 // Some system apps still use directory structure for native libraries 6989 // in which case we might end up not detecting abi solely based on apk 6990 // structure. Try to detect abi based on directory structure. 6991 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 6992 pkg.applicationInfo.primaryCpuAbi == null) { 6993 setBundledAppAbisAndRoots(pkg, pkgSetting); 6994 setNativeLibraryPaths(pkg); 6995 } 6996 6997 } else { 6998 if ((scanFlags & SCAN_MOVE) != 0) { 6999 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7000 // but we already have this packages package info in the PackageSetting. We just 7001 // use that and derive the native library path based on the new codepath. 7002 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7003 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7004 } 7005 7006 // Set native library paths again. For moves, the path will be updated based on the 7007 // ABIs we've determined above. For non-moves, the path will be updated based on the 7008 // ABIs we determined during compilation, but the path will depend on the final 7009 // package path (after the rename away from the stage path). 7010 setNativeLibraryPaths(pkg); 7011 } 7012 7013 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 7014 final int[] userIds = sUserManager.getUserIds(); 7015 synchronized (mInstallLock) { 7016 // Make sure all user data directories are ready to roll; we're okay 7017 // if they already exist 7018 if (!TextUtils.isEmpty(pkg.volumeUuid)) { 7019 for (int userId : userIds) { 7020 if (userId != 0) { 7021 mInstaller.createUserData(pkg.volumeUuid, pkg.packageName, 7022 UserHandle.getUid(userId, pkg.applicationInfo.uid), userId, 7023 pkg.applicationInfo.seinfo); 7024 } 7025 } 7026 } 7027 7028 // Create a native library symlink only if we have native libraries 7029 // and if the native libraries are 32 bit libraries. We do not provide 7030 // this symlink for 64 bit libraries. 7031 if (pkg.applicationInfo.primaryCpuAbi != null && 7032 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 7033 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "linkNativeLib"); 7034 try { 7035 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 7036 for (int userId : userIds) { 7037 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 7038 nativeLibPath, userId) < 0) { 7039 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 7040 "Failed linking native library dir (user=" + userId + ")"); 7041 } 7042 } 7043 } finally { 7044 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7045 } 7046 } 7047 } 7048 7049 // This is a special case for the "system" package, where the ABI is 7050 // dictated by the zygote configuration (and init.rc). We should keep track 7051 // of this ABI so that we can deal with "normal" applications that run under 7052 // the same UID correctly. 7053 if (mPlatformPackage == pkg) { 7054 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7055 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7056 } 7057 7058 // If there's a mismatch between the abi-override in the package setting 7059 // and the abiOverride specified for the install. Warn about this because we 7060 // would've already compiled the app without taking the package setting into 7061 // account. 7062 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7063 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7064 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7065 " for package: " + pkg.packageName); 7066 } 7067 } 7068 7069 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7070 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7071 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7072 7073 // Copy the derived override back to the parsed package, so that we can 7074 // update the package settings accordingly. 7075 pkg.cpuAbiOverride = cpuAbiOverride; 7076 7077 if (DEBUG_ABI_SELECTION) { 7078 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7079 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7080 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7081 } 7082 7083 // Push the derived path down into PackageSettings so we know what to 7084 // clean up at uninstall time. 7085 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7086 7087 if (DEBUG_ABI_SELECTION) { 7088 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7089 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7090 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7091 } 7092 7093 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7094 // We don't do this here during boot because we can do it all 7095 // at once after scanning all existing packages. 7096 // 7097 // We also do this *before* we perform dexopt on this package, so that 7098 // we can avoid redundant dexopts, and also to make sure we've got the 7099 // code and package path correct. 7100 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7101 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); 7102 } 7103 7104 if ((scanFlags & SCAN_NO_DEX) == 0) { 7105 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7106 7107 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, 7108 forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */); 7109 7110 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7111 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7112 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 7113 } 7114 } 7115 if (mFactoryTest && pkg.requestedPermissions.contains( 7116 android.Manifest.permission.FACTORY_TEST)) { 7117 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7118 } 7119 7120 ArrayList<PackageParser.Package> clientLibPkgs = null; 7121 7122 // writer 7123 synchronized (mPackages) { 7124 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7125 // Only system apps can add new shared libraries. 7126 if (pkg.libraryNames != null) { 7127 for (int i=0; i<pkg.libraryNames.size(); i++) { 7128 String name = pkg.libraryNames.get(i); 7129 boolean allowed = false; 7130 if (pkg.isUpdatedSystemApp()) { 7131 // New library entries can only be added through the 7132 // system image. This is important to get rid of a lot 7133 // of nasty edge cases: for example if we allowed a non- 7134 // system update of the app to add a library, then uninstalling 7135 // the update would make the library go away, and assumptions 7136 // we made such as through app install filtering would now 7137 // have allowed apps on the device which aren't compatible 7138 // with it. Better to just have the restriction here, be 7139 // conservative, and create many fewer cases that can negatively 7140 // impact the user experience. 7141 final PackageSetting sysPs = mSettings 7142 .getDisabledSystemPkgLPr(pkg.packageName); 7143 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 7144 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 7145 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 7146 allowed = true; 7147 allowed = true; 7148 break; 7149 } 7150 } 7151 } 7152 } else { 7153 allowed = true; 7154 } 7155 if (allowed) { 7156 if (!mSharedLibraries.containsKey(name)) { 7157 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 7158 } else if (!name.equals(pkg.packageName)) { 7159 Slog.w(TAG, "Package " + pkg.packageName + " library " 7160 + name + " already exists; skipping"); 7161 } 7162 } else { 7163 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 7164 + name + " that is not declared on system image; skipping"); 7165 } 7166 } 7167 if ((scanFlags&SCAN_BOOTING) == 0) { 7168 // If we are not booting, we need to update any applications 7169 // that are clients of our shared library. If we are booting, 7170 // this will all be done once the scan is complete. 7171 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 7172 } 7173 } 7174 } 7175 } 7176 7177 // We also need to dexopt any apps that are dependent on this library. Note that 7178 // if these fail, we should abort the install since installing the library will 7179 // result in some apps being broken. 7180 if (clientLibPkgs != null) { 7181 if ((scanFlags & SCAN_NO_DEX) == 0) { 7182 for (int i = 0; i < clientLibPkgs.size(); i++) { 7183 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7184 int result = mPackageDexOptimizer.performDexOpt(clientPkg, 7185 null /* instruction sets */, forceDex, 7186 (scanFlags & SCAN_DEFER_DEX) != 0, false); 7187 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7188 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 7189 "scanPackageLI failed to dexopt clientLibPkgs"); 7190 } 7191 } 7192 } 7193 } 7194 7195 // Request the ActivityManager to kill the process(only for existing packages) 7196 // so that we do not end up in a confused state while the user is still using the older 7197 // version of the application while the new one gets installed. 7198 if ((scanFlags & SCAN_REPLACING) != 0) { 7199 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 7200 7201 killApplication(pkg.applicationInfo.packageName, 7202 pkg.applicationInfo.uid, "replace pkg"); 7203 7204 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7205 } 7206 7207 // Also need to kill any apps that are dependent on the library. 7208 if (clientLibPkgs != null) { 7209 for (int i=0; i<clientLibPkgs.size(); i++) { 7210 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7211 killApplication(clientPkg.applicationInfo.packageName, 7212 clientPkg.applicationInfo.uid, "update lib"); 7213 } 7214 } 7215 7216 // Make sure we're not adding any bogus keyset info 7217 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7218 ksms.assertScannedPackageValid(pkg); 7219 7220 // writer 7221 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 7222 7223 boolean createIdmapFailed = false; 7224 synchronized (mPackages) { 7225 // We don't expect installation to fail beyond this point 7226 7227 // Add the new setting to mSettings 7228 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 7229 // Add the new setting to mPackages 7230 mPackages.put(pkg.applicationInfo.packageName, pkg); 7231 // Make sure we don't accidentally delete its data. 7232 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 7233 while (iter.hasNext()) { 7234 PackageCleanItem item = iter.next(); 7235 if (pkgName.equals(item.packageName)) { 7236 iter.remove(); 7237 } 7238 } 7239 7240 // Take care of first install / last update times. 7241 if (currentTime != 0) { 7242 if (pkgSetting.firstInstallTime == 0) { 7243 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 7244 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 7245 pkgSetting.lastUpdateTime = currentTime; 7246 } 7247 } else if (pkgSetting.firstInstallTime == 0) { 7248 // We need *something*. Take time time stamp of the file. 7249 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 7250 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 7251 if (scanFileTime != pkgSetting.timeStamp) { 7252 // A package on the system image has changed; consider this 7253 // to be an update. 7254 pkgSetting.lastUpdateTime = scanFileTime; 7255 } 7256 } 7257 7258 // Add the package's KeySets to the global KeySetManagerService 7259 ksms.addScannedPackageLPw(pkg); 7260 7261 int N = pkg.providers.size(); 7262 StringBuilder r = null; 7263 int i; 7264 for (i=0; i<N; i++) { 7265 PackageParser.Provider p = pkg.providers.get(i); 7266 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 7267 p.info.processName, pkg.applicationInfo.uid); 7268 mProviders.addProvider(p); 7269 p.syncable = p.info.isSyncable; 7270 if (p.info.authority != null) { 7271 String names[] = p.info.authority.split(";"); 7272 p.info.authority = null; 7273 for (int j = 0; j < names.length; j++) { 7274 if (j == 1 && p.syncable) { 7275 // We only want the first authority for a provider to possibly be 7276 // syncable, so if we already added this provider using a different 7277 // authority clear the syncable flag. We copy the provider before 7278 // changing it because the mProviders object contains a reference 7279 // to a provider that we don't want to change. 7280 // Only do this for the second authority since the resulting provider 7281 // object can be the same for all future authorities for this provider. 7282 p = new PackageParser.Provider(p); 7283 p.syncable = false; 7284 } 7285 if (!mProvidersByAuthority.containsKey(names[j])) { 7286 mProvidersByAuthority.put(names[j], p); 7287 if (p.info.authority == null) { 7288 p.info.authority = names[j]; 7289 } else { 7290 p.info.authority = p.info.authority + ";" + names[j]; 7291 } 7292 if (DEBUG_PACKAGE_SCANNING) { 7293 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7294 Log.d(TAG, "Registered content provider: " + names[j] 7295 + ", className = " + p.info.name + ", isSyncable = " 7296 + p.info.isSyncable); 7297 } 7298 } else { 7299 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7300 Slog.w(TAG, "Skipping provider name " + names[j] + 7301 " (in package " + pkg.applicationInfo.packageName + 7302 "): name already used by " 7303 + ((other != null && other.getComponentName() != null) 7304 ? other.getComponentName().getPackageName() : "?")); 7305 } 7306 } 7307 } 7308 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7309 if (r == null) { 7310 r = new StringBuilder(256); 7311 } else { 7312 r.append(' '); 7313 } 7314 r.append(p.info.name); 7315 } 7316 } 7317 if (r != null) { 7318 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 7319 } 7320 7321 N = pkg.services.size(); 7322 r = null; 7323 for (i=0; i<N; i++) { 7324 PackageParser.Service s = pkg.services.get(i); 7325 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 7326 s.info.processName, pkg.applicationInfo.uid); 7327 mServices.addService(s); 7328 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7329 if (r == null) { 7330 r = new StringBuilder(256); 7331 } else { 7332 r.append(' '); 7333 } 7334 r.append(s.info.name); 7335 } 7336 } 7337 if (r != null) { 7338 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 7339 } 7340 7341 N = pkg.receivers.size(); 7342 r = null; 7343 for (i=0; i<N; i++) { 7344 PackageParser.Activity a = pkg.receivers.get(i); 7345 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 7346 a.info.processName, pkg.applicationInfo.uid); 7347 mReceivers.addActivity(a, "receiver"); 7348 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7349 if (r == null) { 7350 r = new StringBuilder(256); 7351 } else { 7352 r.append(' '); 7353 } 7354 r.append(a.info.name); 7355 } 7356 } 7357 if (r != null) { 7358 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 7359 } 7360 7361 N = pkg.activities.size(); 7362 r = null; 7363 for (i=0; i<N; i++) { 7364 PackageParser.Activity a = pkg.activities.get(i); 7365 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 7366 a.info.processName, pkg.applicationInfo.uid); 7367 mActivities.addActivity(a, "activity"); 7368 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7369 if (r == null) { 7370 r = new StringBuilder(256); 7371 } else { 7372 r.append(' '); 7373 } 7374 r.append(a.info.name); 7375 } 7376 } 7377 if (r != null) { 7378 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 7379 } 7380 7381 N = pkg.permissionGroups.size(); 7382 r = null; 7383 for (i=0; i<N; i++) { 7384 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 7385 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 7386 if (cur == null) { 7387 mPermissionGroups.put(pg.info.name, pg); 7388 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7389 if (r == null) { 7390 r = new StringBuilder(256); 7391 } else { 7392 r.append(' '); 7393 } 7394 r.append(pg.info.name); 7395 } 7396 } else { 7397 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 7398 + pg.info.packageName + " ignored: original from " 7399 + cur.info.packageName); 7400 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7401 if (r == null) { 7402 r = new StringBuilder(256); 7403 } else { 7404 r.append(' '); 7405 } 7406 r.append("DUP:"); 7407 r.append(pg.info.name); 7408 } 7409 } 7410 } 7411 if (r != null) { 7412 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 7413 } 7414 7415 N = pkg.permissions.size(); 7416 r = null; 7417 for (i=0; i<N; i++) { 7418 PackageParser.Permission p = pkg.permissions.get(i); 7419 7420 // Assume by default that we did not install this permission into the system. 7421 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 7422 7423 // Now that permission groups have a special meaning, we ignore permission 7424 // groups for legacy apps to prevent unexpected behavior. In particular, 7425 // permissions for one app being granted to someone just becuase they happen 7426 // to be in a group defined by another app (before this had no implications). 7427 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 7428 p.group = mPermissionGroups.get(p.info.group); 7429 // Warn for a permission in an unknown group. 7430 if (p.info.group != null && p.group == null) { 7431 Slog.w(TAG, "Permission " + p.info.name + " from package " 7432 + p.info.packageName + " in an unknown group " + p.info.group); 7433 } 7434 } 7435 7436 ArrayMap<String, BasePermission> permissionMap = 7437 p.tree ? mSettings.mPermissionTrees 7438 : mSettings.mPermissions; 7439 BasePermission bp = permissionMap.get(p.info.name); 7440 7441 // Allow system apps to redefine non-system permissions 7442 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 7443 final boolean currentOwnerIsSystem = (bp.perm != null 7444 && isSystemApp(bp.perm.owner)); 7445 if (isSystemApp(p.owner)) { 7446 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 7447 // It's a built-in permission and no owner, take ownership now 7448 bp.packageSetting = pkgSetting; 7449 bp.perm = p; 7450 bp.uid = pkg.applicationInfo.uid; 7451 bp.sourcePackage = p.info.packageName; 7452 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 7453 } else if (!currentOwnerIsSystem) { 7454 String msg = "New decl " + p.owner + " of permission " 7455 + p.info.name + " is system; overriding " + bp.sourcePackage; 7456 reportSettingsProblem(Log.WARN, msg); 7457 bp = null; 7458 } 7459 } 7460 } 7461 7462 if (bp == null) { 7463 bp = new BasePermission(p.info.name, p.info.packageName, 7464 BasePermission.TYPE_NORMAL); 7465 permissionMap.put(p.info.name, bp); 7466 } 7467 7468 if (bp.perm == null) { 7469 if (bp.sourcePackage == null 7470 || bp.sourcePackage.equals(p.info.packageName)) { 7471 BasePermission tree = findPermissionTreeLP(p.info.name); 7472 if (tree == null 7473 || tree.sourcePackage.equals(p.info.packageName)) { 7474 bp.packageSetting = pkgSetting; 7475 bp.perm = p; 7476 bp.uid = pkg.applicationInfo.uid; 7477 bp.sourcePackage = p.info.packageName; 7478 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 7479 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7480 if (r == null) { 7481 r = new StringBuilder(256); 7482 } else { 7483 r.append(' '); 7484 } 7485 r.append(p.info.name); 7486 } 7487 } else { 7488 Slog.w(TAG, "Permission " + p.info.name + " from package " 7489 + p.info.packageName + " ignored: base tree " 7490 + tree.name + " is from package " 7491 + tree.sourcePackage); 7492 } 7493 } else { 7494 Slog.w(TAG, "Permission " + p.info.name + " from package " 7495 + p.info.packageName + " ignored: original from " 7496 + bp.sourcePackage); 7497 } 7498 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7499 if (r == null) { 7500 r = new StringBuilder(256); 7501 } else { 7502 r.append(' '); 7503 } 7504 r.append("DUP:"); 7505 r.append(p.info.name); 7506 } 7507 if (bp.perm == p) { 7508 bp.protectionLevel = p.info.protectionLevel; 7509 } 7510 } 7511 7512 if (r != null) { 7513 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 7514 } 7515 7516 N = pkg.instrumentation.size(); 7517 r = null; 7518 for (i=0; i<N; i++) { 7519 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 7520 a.info.packageName = pkg.applicationInfo.packageName; 7521 a.info.sourceDir = pkg.applicationInfo.sourceDir; 7522 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 7523 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 7524 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 7525 a.info.dataDir = pkg.applicationInfo.dataDir; 7526 7527 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 7528 // need other information about the application, like the ABI and what not ? 7529 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 7530 mInstrumentation.put(a.getComponentName(), a); 7531 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7532 if (r == null) { 7533 r = new StringBuilder(256); 7534 } else { 7535 r.append(' '); 7536 } 7537 r.append(a.info.name); 7538 } 7539 } 7540 if (r != null) { 7541 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 7542 } 7543 7544 if (pkg.protectedBroadcasts != null) { 7545 N = pkg.protectedBroadcasts.size(); 7546 for (i=0; i<N; i++) { 7547 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 7548 } 7549 } 7550 7551 pkgSetting.setTimeStamp(scanFileTime); 7552 7553 // Create idmap files for pairs of (packages, overlay packages). 7554 // Note: "android", ie framework-res.apk, is handled by native layers. 7555 if (pkg.mOverlayTarget != null) { 7556 // This is an overlay package. 7557 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 7558 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 7559 mOverlays.put(pkg.mOverlayTarget, 7560 new ArrayMap<String, PackageParser.Package>()); 7561 } 7562 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 7563 map.put(pkg.packageName, pkg); 7564 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 7565 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 7566 createIdmapFailed = true; 7567 } 7568 } 7569 } else if (mOverlays.containsKey(pkg.packageName) && 7570 !pkg.packageName.equals("android")) { 7571 // This is a regular package, with one or more known overlay packages. 7572 createIdmapsForPackageLI(pkg); 7573 } 7574 } 7575 7576 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7577 7578 if (createIdmapFailed) { 7579 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7580 "scanPackageLI failed to createIdmap"); 7581 } 7582 return pkg; 7583 } 7584 7585 /** 7586 * Derive the ABI of a non-system package located at {@code scanFile}. This information 7587 * is derived purely on the basis of the contents of {@code scanFile} and 7588 * {@code cpuAbiOverride}. 7589 * 7590 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 7591 */ 7592 public void derivePackageAbi(PackageParser.Package pkg, File scanFile, 7593 String cpuAbiOverride, boolean extractLibs) 7594 throws PackageManagerException { 7595 // TODO: We can probably be smarter about this stuff. For installed apps, 7596 // we can calculate this information at install time once and for all. For 7597 // system apps, we can probably assume that this information doesn't change 7598 // after the first boot scan. As things stand, we do lots of unnecessary work. 7599 7600 // Give ourselves some initial paths; we'll come back for another 7601 // pass once we've determined ABI below. 7602 setNativeLibraryPaths(pkg); 7603 7604 // We would never need to extract libs for forward-locked and external packages, 7605 // since the container service will do it for us. We shouldn't attempt to 7606 // extract libs from system app when it was not updated. 7607 if (pkg.isForwardLocked() || isExternal(pkg) || 7608 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) ) { 7609 extractLibs = false; 7610 } 7611 7612 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 7613 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 7614 7615 NativeLibraryHelper.Handle handle = null; 7616 try { 7617 handle = NativeLibraryHelper.Handle.create(pkg); 7618 // TODO(multiArch): This can be null for apps that didn't go through the 7619 // usual installation process. We can calculate it again, like we 7620 // do during install time. 7621 // 7622 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 7623 // unnecessary. 7624 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 7625 7626 // Null out the abis so that they can be recalculated. 7627 pkg.applicationInfo.primaryCpuAbi = null; 7628 pkg.applicationInfo.secondaryCpuAbi = null; 7629 if (isMultiArch(pkg.applicationInfo)) { 7630 // Warn if we've set an abiOverride for multi-lib packages.. 7631 // By definition, we need to copy both 32 and 64 bit libraries for 7632 // such packages. 7633 if (pkg.cpuAbiOverride != null 7634 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 7635 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 7636 } 7637 7638 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 7639 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 7640 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 7641 if (extractLibs) { 7642 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7643 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 7644 useIsaSpecificSubdirs); 7645 } else { 7646 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 7647 } 7648 } 7649 7650 maybeThrowExceptionForMultiArchCopy( 7651 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 7652 7653 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 7654 if (extractLibs) { 7655 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7656 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 7657 useIsaSpecificSubdirs); 7658 } else { 7659 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 7660 } 7661 } 7662 7663 maybeThrowExceptionForMultiArchCopy( 7664 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 7665 7666 if (abi64 >= 0) { 7667 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 7668 } 7669 7670 if (abi32 >= 0) { 7671 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 7672 if (abi64 >= 0) { 7673 pkg.applicationInfo.secondaryCpuAbi = abi; 7674 } else { 7675 pkg.applicationInfo.primaryCpuAbi = abi; 7676 } 7677 } 7678 } else { 7679 String[] abiList = (cpuAbiOverride != null) ? 7680 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 7681 7682 // Enable gross and lame hacks for apps that are built with old 7683 // SDK tools. We must scan their APKs for renderscript bitcode and 7684 // not launch them if it's present. Don't bother checking on devices 7685 // that don't have 64 bit support. 7686 boolean needsRenderScriptOverride = false; 7687 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 7688 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 7689 abiList = Build.SUPPORTED_32_BIT_ABIS; 7690 needsRenderScriptOverride = true; 7691 } 7692 7693 final int copyRet; 7694 if (extractLibs) { 7695 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7696 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 7697 } else { 7698 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 7699 } 7700 7701 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 7702 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 7703 "Error unpackaging native libs for app, errorCode=" + copyRet); 7704 } 7705 7706 if (copyRet >= 0) { 7707 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 7708 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 7709 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 7710 } else if (needsRenderScriptOverride) { 7711 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 7712 } 7713 } 7714 } catch (IOException ioe) { 7715 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 7716 } finally { 7717 IoUtils.closeQuietly(handle); 7718 } 7719 7720 // Now that we've calculated the ABIs and determined if it's an internal app, 7721 // we will go ahead and populate the nativeLibraryPath. 7722 setNativeLibraryPaths(pkg); 7723 } 7724 7725 /** 7726 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 7727 * i.e, so that all packages can be run inside a single process if required. 7728 * 7729 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 7730 * this function will either try and make the ABI for all packages in {@code packagesForUser} 7731 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 7732 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 7733 * updating a package that belongs to a shared user. 7734 * 7735 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 7736 * adds unnecessary complexity. 7737 */ 7738 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 7739 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { 7740 String requiredInstructionSet = null; 7741 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 7742 requiredInstructionSet = VMRuntime.getInstructionSet( 7743 scannedPackage.applicationInfo.primaryCpuAbi); 7744 } 7745 7746 PackageSetting requirer = null; 7747 for (PackageSetting ps : packagesForUser) { 7748 // If packagesForUser contains scannedPackage, we skip it. This will happen 7749 // when scannedPackage is an update of an existing package. Without this check, 7750 // we will never be able to change the ABI of any package belonging to a shared 7751 // user, even if it's compatible with other packages. 7752 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7753 if (ps.primaryCpuAbiString == null) { 7754 continue; 7755 } 7756 7757 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 7758 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 7759 // We have a mismatch between instruction sets (say arm vs arm64) warn about 7760 // this but there's not much we can do. 7761 String errorMessage = "Instruction set mismatch, " 7762 + ((requirer == null) ? "[caller]" : requirer) 7763 + " requires " + requiredInstructionSet + " whereas " + ps 7764 + " requires " + instructionSet; 7765 Slog.w(TAG, errorMessage); 7766 } 7767 7768 if (requiredInstructionSet == null) { 7769 requiredInstructionSet = instructionSet; 7770 requirer = ps; 7771 } 7772 } 7773 } 7774 7775 if (requiredInstructionSet != null) { 7776 String adjustedAbi; 7777 if (requirer != null) { 7778 // requirer != null implies that either scannedPackage was null or that scannedPackage 7779 // did not require an ABI, in which case we have to adjust scannedPackage to match 7780 // the ABI of the set (which is the same as requirer's ABI) 7781 adjustedAbi = requirer.primaryCpuAbiString; 7782 if (scannedPackage != null) { 7783 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 7784 } 7785 } else { 7786 // requirer == null implies that we're updating all ABIs in the set to 7787 // match scannedPackage. 7788 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 7789 } 7790 7791 for (PackageSetting ps : packagesForUser) { 7792 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7793 if (ps.primaryCpuAbiString != null) { 7794 continue; 7795 } 7796 7797 ps.primaryCpuAbiString = adjustedAbi; 7798 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 7799 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 7800 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 7801 7802 int result = mPackageDexOptimizer.performDexOpt(ps.pkg, 7803 null /* instruction sets */, forceDexOpt, deferDexOpt, true); 7804 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7805 ps.primaryCpuAbiString = null; 7806 ps.pkg.applicationInfo.primaryCpuAbi = null; 7807 return; 7808 } else { 7809 mInstaller.rmdex(ps.codePathString, 7810 getDexCodeInstructionSet(getPreferredInstructionSet())); 7811 } 7812 } 7813 } 7814 } 7815 } 7816 } 7817 7818 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 7819 synchronized (mPackages) { 7820 mResolverReplaced = true; 7821 // Set up information for custom user intent resolution activity. 7822 mResolveActivity.applicationInfo = pkg.applicationInfo; 7823 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 7824 mResolveActivity.packageName = pkg.applicationInfo.packageName; 7825 mResolveActivity.processName = pkg.applicationInfo.packageName; 7826 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7827 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 7828 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 7829 mResolveActivity.theme = 0; 7830 mResolveActivity.exported = true; 7831 mResolveActivity.enabled = true; 7832 mResolveInfo.activityInfo = mResolveActivity; 7833 mResolveInfo.priority = 0; 7834 mResolveInfo.preferredOrder = 0; 7835 mResolveInfo.match = 0; 7836 mResolveComponentName = mCustomResolverComponentName; 7837 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 7838 mResolveComponentName); 7839 } 7840 } 7841 7842 private static String calculateBundledApkRoot(final String codePathString) { 7843 final File codePath = new File(codePathString); 7844 final File codeRoot; 7845 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 7846 codeRoot = Environment.getRootDirectory(); 7847 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 7848 codeRoot = Environment.getOemDirectory(); 7849 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 7850 codeRoot = Environment.getVendorDirectory(); 7851 } else { 7852 // Unrecognized code path; take its top real segment as the apk root: 7853 // e.g. /something/app/blah.apk => /something 7854 try { 7855 File f = codePath.getCanonicalFile(); 7856 File parent = f.getParentFile(); // non-null because codePath is a file 7857 File tmp; 7858 while ((tmp = parent.getParentFile()) != null) { 7859 f = parent; 7860 parent = tmp; 7861 } 7862 codeRoot = f; 7863 Slog.w(TAG, "Unrecognized code path " 7864 + codePath + " - using " + codeRoot); 7865 } catch (IOException e) { 7866 // Can't canonicalize the code path -- shenanigans? 7867 Slog.w(TAG, "Can't canonicalize code path " + codePath); 7868 return Environment.getRootDirectory().getPath(); 7869 } 7870 } 7871 return codeRoot.getPath(); 7872 } 7873 7874 /** 7875 * Derive and set the location of native libraries for the given package, 7876 * which varies depending on where and how the package was installed. 7877 */ 7878 private void setNativeLibraryPaths(PackageParser.Package pkg) { 7879 final ApplicationInfo info = pkg.applicationInfo; 7880 final String codePath = pkg.codePath; 7881 final File codeFile = new File(codePath); 7882 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 7883 final boolean asecApp = info.isForwardLocked() || isExternal(info); 7884 7885 info.nativeLibraryRootDir = null; 7886 info.nativeLibraryRootRequiresIsa = false; 7887 info.nativeLibraryDir = null; 7888 info.secondaryNativeLibraryDir = null; 7889 7890 if (isApkFile(codeFile)) { 7891 // Monolithic install 7892 if (bundledApp) { 7893 // If "/system/lib64/apkname" exists, assume that is the per-package 7894 // native library directory to use; otherwise use "/system/lib/apkname". 7895 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 7896 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 7897 getPrimaryInstructionSet(info)); 7898 7899 // This is a bundled system app so choose the path based on the ABI. 7900 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 7901 // is just the default path. 7902 final String apkName = deriveCodePathName(codePath); 7903 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 7904 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 7905 apkName).getAbsolutePath(); 7906 7907 if (info.secondaryCpuAbi != null) { 7908 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 7909 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 7910 secondaryLibDir, apkName).getAbsolutePath(); 7911 } 7912 } else if (asecApp) { 7913 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 7914 .getAbsolutePath(); 7915 } else { 7916 final String apkName = deriveCodePathName(codePath); 7917 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 7918 .getAbsolutePath(); 7919 } 7920 7921 info.nativeLibraryRootRequiresIsa = false; 7922 info.nativeLibraryDir = info.nativeLibraryRootDir; 7923 } else { 7924 // Cluster install 7925 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 7926 info.nativeLibraryRootRequiresIsa = true; 7927 7928 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 7929 getPrimaryInstructionSet(info)).getAbsolutePath(); 7930 7931 if (info.secondaryCpuAbi != null) { 7932 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 7933 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 7934 } 7935 } 7936 } 7937 7938 /** 7939 * Calculate the abis and roots for a bundled app. These can uniquely 7940 * be determined from the contents of the system partition, i.e whether 7941 * it contains 64 or 32 bit shared libraries etc. We do not validate any 7942 * of this information, and instead assume that the system was built 7943 * sensibly. 7944 */ 7945 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 7946 PackageSetting pkgSetting) { 7947 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 7948 7949 // If "/system/lib64/apkname" exists, assume that is the per-package 7950 // native library directory to use; otherwise use "/system/lib/apkname". 7951 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 7952 setBundledAppAbi(pkg, apkRoot, apkName); 7953 // pkgSetting might be null during rescan following uninstall of updates 7954 // to a bundled app, so accommodate that possibility. The settings in 7955 // that case will be established later from the parsed package. 7956 // 7957 // If the settings aren't null, sync them up with what we've just derived. 7958 // note that apkRoot isn't stored in the package settings. 7959 if (pkgSetting != null) { 7960 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7961 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7962 } 7963 } 7964 7965 /** 7966 * Deduces the ABI of a bundled app and sets the relevant fields on the 7967 * parsed pkg object. 7968 * 7969 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 7970 * under which system libraries are installed. 7971 * @param apkName the name of the installed package. 7972 */ 7973 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 7974 final File codeFile = new File(pkg.codePath); 7975 7976 final boolean has64BitLibs; 7977 final boolean has32BitLibs; 7978 if (isApkFile(codeFile)) { 7979 // Monolithic install 7980 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 7981 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 7982 } else { 7983 // Cluster install 7984 final File rootDir = new File(codeFile, LIB_DIR_NAME); 7985 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 7986 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 7987 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 7988 has64BitLibs = (new File(rootDir, isa)).exists(); 7989 } else { 7990 has64BitLibs = false; 7991 } 7992 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 7993 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 7994 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 7995 has32BitLibs = (new File(rootDir, isa)).exists(); 7996 } else { 7997 has32BitLibs = false; 7998 } 7999 } 8000 8001 if (has64BitLibs && !has32BitLibs) { 8002 // The package has 64 bit libs, but not 32 bit libs. Its primary 8003 // ABI should be 64 bit. We can safely assume here that the bundled 8004 // native libraries correspond to the most preferred ABI in the list. 8005 8006 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8007 pkg.applicationInfo.secondaryCpuAbi = null; 8008 } else if (has32BitLibs && !has64BitLibs) { 8009 // The package has 32 bit libs but not 64 bit libs. Its primary 8010 // ABI should be 32 bit. 8011 8012 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8013 pkg.applicationInfo.secondaryCpuAbi = null; 8014 } else if (has32BitLibs && has64BitLibs) { 8015 // The application has both 64 and 32 bit bundled libraries. We check 8016 // here that the app declares multiArch support, and warn if it doesn't. 8017 // 8018 // We will be lenient here and record both ABIs. The primary will be the 8019 // ABI that's higher on the list, i.e, a device that's configured to prefer 8020 // 64 bit apps will see a 64 bit primary ABI, 8021 8022 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8023 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 8024 } 8025 8026 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8027 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8028 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8029 } else { 8030 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8031 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8032 } 8033 } else { 8034 pkg.applicationInfo.primaryCpuAbi = null; 8035 pkg.applicationInfo.secondaryCpuAbi = null; 8036 } 8037 } 8038 8039 private void killApplication(String pkgName, int appId, String reason) { 8040 // Request the ActivityManager to kill the process(only for existing packages) 8041 // so that we do not end up in a confused state while the user is still using the older 8042 // version of the application while the new one gets installed. 8043 IActivityManager am = ActivityManagerNative.getDefault(); 8044 if (am != null) { 8045 try { 8046 am.killApplicationWithAppId(pkgName, appId, reason); 8047 } catch (RemoteException e) { 8048 } 8049 } 8050 } 8051 8052 void removePackageLI(PackageSetting ps, boolean chatty) { 8053 if (DEBUG_INSTALL) { 8054 if (chatty) 8055 Log.d(TAG, "Removing package " + ps.name); 8056 } 8057 8058 // writer 8059 synchronized (mPackages) { 8060 mPackages.remove(ps.name); 8061 final PackageParser.Package pkg = ps.pkg; 8062 if (pkg != null) { 8063 cleanPackageDataStructuresLILPw(pkg, chatty); 8064 } 8065 } 8066 } 8067 8068 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8069 if (DEBUG_INSTALL) { 8070 if (chatty) 8071 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8072 } 8073 8074 // writer 8075 synchronized (mPackages) { 8076 mPackages.remove(pkg.applicationInfo.packageName); 8077 cleanPackageDataStructuresLILPw(pkg, chatty); 8078 } 8079 } 8080 8081 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8082 int N = pkg.providers.size(); 8083 StringBuilder r = null; 8084 int i; 8085 for (i=0; i<N; i++) { 8086 PackageParser.Provider p = pkg.providers.get(i); 8087 mProviders.removeProvider(p); 8088 if (p.info.authority == null) { 8089 8090 /* There was another ContentProvider with this authority when 8091 * this app was installed so this authority is null, 8092 * Ignore it as we don't have to unregister the provider. 8093 */ 8094 continue; 8095 } 8096 String names[] = p.info.authority.split(";"); 8097 for (int j = 0; j < names.length; j++) { 8098 if (mProvidersByAuthority.get(names[j]) == p) { 8099 mProvidersByAuthority.remove(names[j]); 8100 if (DEBUG_REMOVE) { 8101 if (chatty) 8102 Log.d(TAG, "Unregistered content provider: " + names[j] 8103 + ", className = " + p.info.name + ", isSyncable = " 8104 + p.info.isSyncable); 8105 } 8106 } 8107 } 8108 if (DEBUG_REMOVE && chatty) { 8109 if (r == null) { 8110 r = new StringBuilder(256); 8111 } else { 8112 r.append(' '); 8113 } 8114 r.append(p.info.name); 8115 } 8116 } 8117 if (r != null) { 8118 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 8119 } 8120 8121 N = pkg.services.size(); 8122 r = null; 8123 for (i=0; i<N; i++) { 8124 PackageParser.Service s = pkg.services.get(i); 8125 mServices.removeService(s); 8126 if (chatty) { 8127 if (r == null) { 8128 r = new StringBuilder(256); 8129 } else { 8130 r.append(' '); 8131 } 8132 r.append(s.info.name); 8133 } 8134 } 8135 if (r != null) { 8136 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 8137 } 8138 8139 N = pkg.receivers.size(); 8140 r = null; 8141 for (i=0; i<N; i++) { 8142 PackageParser.Activity a = pkg.receivers.get(i); 8143 mReceivers.removeActivity(a, "receiver"); 8144 if (DEBUG_REMOVE && chatty) { 8145 if (r == null) { 8146 r = new StringBuilder(256); 8147 } else { 8148 r.append(' '); 8149 } 8150 r.append(a.info.name); 8151 } 8152 } 8153 if (r != null) { 8154 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 8155 } 8156 8157 N = pkg.activities.size(); 8158 r = null; 8159 for (i=0; i<N; i++) { 8160 PackageParser.Activity a = pkg.activities.get(i); 8161 mActivities.removeActivity(a, "activity"); 8162 if (DEBUG_REMOVE && chatty) { 8163 if (r == null) { 8164 r = new StringBuilder(256); 8165 } else { 8166 r.append(' '); 8167 } 8168 r.append(a.info.name); 8169 } 8170 } 8171 if (r != null) { 8172 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 8173 } 8174 8175 N = pkg.permissions.size(); 8176 r = null; 8177 for (i=0; i<N; i++) { 8178 PackageParser.Permission p = pkg.permissions.get(i); 8179 BasePermission bp = mSettings.mPermissions.get(p.info.name); 8180 if (bp == null) { 8181 bp = mSettings.mPermissionTrees.get(p.info.name); 8182 } 8183 if (bp != null && bp.perm == p) { 8184 bp.perm = null; 8185 if (DEBUG_REMOVE && chatty) { 8186 if (r == null) { 8187 r = new StringBuilder(256); 8188 } else { 8189 r.append(' '); 8190 } 8191 r.append(p.info.name); 8192 } 8193 } 8194 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8195 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 8196 if (appOpPerms != null) { 8197 appOpPerms.remove(pkg.packageName); 8198 } 8199 } 8200 } 8201 if (r != null) { 8202 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8203 } 8204 8205 N = pkg.requestedPermissions.size(); 8206 r = null; 8207 for (i=0; i<N; i++) { 8208 String perm = pkg.requestedPermissions.get(i); 8209 BasePermission bp = mSettings.mPermissions.get(perm); 8210 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8211 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 8212 if (appOpPerms != null) { 8213 appOpPerms.remove(pkg.packageName); 8214 if (appOpPerms.isEmpty()) { 8215 mAppOpPermissionPackages.remove(perm); 8216 } 8217 } 8218 } 8219 } 8220 if (r != null) { 8221 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8222 } 8223 8224 N = pkg.instrumentation.size(); 8225 r = null; 8226 for (i=0; i<N; i++) { 8227 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8228 mInstrumentation.remove(a.getComponentName()); 8229 if (DEBUG_REMOVE && chatty) { 8230 if (r == null) { 8231 r = new StringBuilder(256); 8232 } else { 8233 r.append(' '); 8234 } 8235 r.append(a.info.name); 8236 } 8237 } 8238 if (r != null) { 8239 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 8240 } 8241 8242 r = null; 8243 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8244 // Only system apps can hold shared libraries. 8245 if (pkg.libraryNames != null) { 8246 for (i=0; i<pkg.libraryNames.size(); i++) { 8247 String name = pkg.libraryNames.get(i); 8248 SharedLibraryEntry cur = mSharedLibraries.get(name); 8249 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 8250 mSharedLibraries.remove(name); 8251 if (DEBUG_REMOVE && chatty) { 8252 if (r == null) { 8253 r = new StringBuilder(256); 8254 } else { 8255 r.append(' '); 8256 } 8257 r.append(name); 8258 } 8259 } 8260 } 8261 } 8262 } 8263 if (r != null) { 8264 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 8265 } 8266 } 8267 8268 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 8269 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 8270 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 8271 return true; 8272 } 8273 } 8274 return false; 8275 } 8276 8277 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 8278 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 8279 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 8280 8281 private void updatePermissionsLPw(String changingPkg, 8282 PackageParser.Package pkgInfo, int flags) { 8283 // Make sure there are no dangling permission trees. 8284 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 8285 while (it.hasNext()) { 8286 final BasePermission bp = it.next(); 8287 if (bp.packageSetting == null) { 8288 // We may not yet have parsed the package, so just see if 8289 // we still know about its settings. 8290 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 8291 } 8292 if (bp.packageSetting == null) { 8293 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 8294 + " from package " + bp.sourcePackage); 8295 it.remove(); 8296 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 8297 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 8298 Slog.i(TAG, "Removing old permission tree: " + bp.name 8299 + " from package " + bp.sourcePackage); 8300 flags |= UPDATE_PERMISSIONS_ALL; 8301 it.remove(); 8302 } 8303 } 8304 } 8305 8306 // Make sure all dynamic permissions have been assigned to a package, 8307 // and make sure there are no dangling permissions. 8308 it = mSettings.mPermissions.values().iterator(); 8309 while (it.hasNext()) { 8310 final BasePermission bp = it.next(); 8311 if (bp.type == BasePermission.TYPE_DYNAMIC) { 8312 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 8313 + bp.name + " pkg=" + bp.sourcePackage 8314 + " info=" + bp.pendingInfo); 8315 if (bp.packageSetting == null && bp.pendingInfo != null) { 8316 final BasePermission tree = findPermissionTreeLP(bp.name); 8317 if (tree != null && tree.perm != null) { 8318 bp.packageSetting = tree.packageSetting; 8319 bp.perm = new PackageParser.Permission(tree.perm.owner, 8320 new PermissionInfo(bp.pendingInfo)); 8321 bp.perm.info.packageName = tree.perm.info.packageName; 8322 bp.perm.info.name = bp.name; 8323 bp.uid = tree.uid; 8324 } 8325 } 8326 } 8327 if (bp.packageSetting == null) { 8328 // We may not yet have parsed the package, so just see if 8329 // we still know about its settings. 8330 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 8331 } 8332 if (bp.packageSetting == null) { 8333 Slog.w(TAG, "Removing dangling permission: " + bp.name 8334 + " from package " + bp.sourcePackage); 8335 it.remove(); 8336 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 8337 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 8338 Slog.i(TAG, "Removing old permission: " + bp.name 8339 + " from package " + bp.sourcePackage); 8340 flags |= UPDATE_PERMISSIONS_ALL; 8341 it.remove(); 8342 } 8343 } 8344 } 8345 8346 // Now update the permissions for all packages, in particular 8347 // replace the granted permissions of the system packages. 8348 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 8349 for (PackageParser.Package pkg : mPackages.values()) { 8350 if (pkg != pkgInfo) { 8351 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0, 8352 changingPkg); 8353 } 8354 } 8355 } 8356 8357 if (pkgInfo != null) { 8358 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg); 8359 } 8360 } 8361 8362 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 8363 String packageOfInterest) { 8364 // IMPORTANT: There are two types of permissions: install and runtime. 8365 // Install time permissions are granted when the app is installed to 8366 // all device users and users added in the future. Runtime permissions 8367 // are granted at runtime explicitly to specific users. Normal and signature 8368 // protected permissions are install time permissions. Dangerous permissions 8369 // are install permissions if the app's target SDK is Lollipop MR1 or older, 8370 // otherwise they are runtime permissions. This function does not manage 8371 // runtime permissions except for the case an app targeting Lollipop MR1 8372 // being upgraded to target a newer SDK, in which case dangerous permissions 8373 // are transformed from install time to runtime ones. 8374 8375 final PackageSetting ps = (PackageSetting) pkg.mExtras; 8376 if (ps == null) { 8377 return; 8378 } 8379 8380 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 8381 8382 PermissionsState permissionsState = ps.getPermissionsState(); 8383 PermissionsState origPermissions = permissionsState; 8384 8385 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 8386 8387 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 8388 8389 boolean changedInstallPermission = false; 8390 8391 if (replace) { 8392 ps.installPermissionsFixed = false; 8393 if (!ps.isSharedUser()) { 8394 origPermissions = new PermissionsState(permissionsState); 8395 permissionsState.reset(); 8396 } 8397 } 8398 8399 permissionsState.setGlobalGids(mGlobalGids); 8400 8401 final int N = pkg.requestedPermissions.size(); 8402 for (int i=0; i<N; i++) { 8403 final String name = pkg.requestedPermissions.get(i); 8404 final BasePermission bp = mSettings.mPermissions.get(name); 8405 8406 if (DEBUG_INSTALL) { 8407 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 8408 } 8409 8410 if (bp == null || bp.packageSetting == null) { 8411 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 8412 Slog.w(TAG, "Unknown permission " + name 8413 + " in package " + pkg.packageName); 8414 } 8415 continue; 8416 } 8417 8418 final String perm = bp.name; 8419 boolean allowedSig = false; 8420 int grant = GRANT_DENIED; 8421 8422 // Keep track of app op permissions. 8423 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8424 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 8425 if (pkgs == null) { 8426 pkgs = new ArraySet<>(); 8427 mAppOpPermissionPackages.put(bp.name, pkgs); 8428 } 8429 pkgs.add(pkg.packageName); 8430 } 8431 8432 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 8433 switch (level) { 8434 case PermissionInfo.PROTECTION_NORMAL: { 8435 // For all apps normal permissions are install time ones. 8436 grant = GRANT_INSTALL; 8437 } break; 8438 8439 case PermissionInfo.PROTECTION_DANGEROUS: { 8440 if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) { 8441 // For legacy apps dangerous permissions are install time ones. 8442 grant = GRANT_INSTALL_LEGACY; 8443 } else if (origPermissions.hasInstallPermission(bp.name)) { 8444 // For legacy apps that became modern, install becomes runtime. 8445 grant = GRANT_UPGRADE; 8446 } else { 8447 // For modern apps keep runtime permissions unchanged. 8448 grant = GRANT_RUNTIME; 8449 } 8450 } break; 8451 8452 case PermissionInfo.PROTECTION_SIGNATURE: { 8453 // For all apps signature permissions are install time ones. 8454 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 8455 if (allowedSig) { 8456 grant = GRANT_INSTALL; 8457 } 8458 } break; 8459 } 8460 8461 if (DEBUG_INSTALL) { 8462 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 8463 } 8464 8465 if (grant != GRANT_DENIED) { 8466 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 8467 // If this is an existing, non-system package, then 8468 // we can't add any new permissions to it. 8469 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 8470 // Except... if this is a permission that was added 8471 // to the platform (note: need to only do this when 8472 // updating the platform). 8473 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 8474 grant = GRANT_DENIED; 8475 } 8476 } 8477 } 8478 8479 switch (grant) { 8480 case GRANT_INSTALL: { 8481 // Revoke this as runtime permission to handle the case of 8482 // a runtime permission being downgraded to an install one. 8483 for (int userId : UserManagerService.getInstance().getUserIds()) { 8484 if (origPermissions.getRuntimePermissionState( 8485 bp.name, userId) != null) { 8486 // Revoke the runtime permission and clear the flags. 8487 origPermissions.revokeRuntimePermission(bp, userId); 8488 origPermissions.updatePermissionFlags(bp, userId, 8489 PackageManager.MASK_PERMISSION_FLAGS, 0); 8490 // If we revoked a permission permission, we have to write. 8491 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8492 changedRuntimePermissionUserIds, userId); 8493 } 8494 } 8495 // Grant an install permission. 8496 if (permissionsState.grantInstallPermission(bp) != 8497 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8498 changedInstallPermission = true; 8499 } 8500 } break; 8501 8502 case GRANT_INSTALL_LEGACY: { 8503 // Grant an install permission. 8504 if (permissionsState.grantInstallPermission(bp) != 8505 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8506 changedInstallPermission = true; 8507 } 8508 } break; 8509 8510 case GRANT_RUNTIME: { 8511 // Grant previously granted runtime permissions. 8512 for (int userId : UserManagerService.getInstance().getUserIds()) { 8513 PermissionState permissionState = origPermissions 8514 .getRuntimePermissionState(bp.name, userId); 8515 final int flags = permissionState != null 8516 ? permissionState.getFlags() : 0; 8517 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 8518 if (permissionsState.grantRuntimePermission(bp, userId) == 8519 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8520 // If we cannot put the permission as it was, we have to write. 8521 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8522 changedRuntimePermissionUserIds, userId); 8523 } 8524 } 8525 // Propagate the permission flags. 8526 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 8527 } 8528 } break; 8529 8530 case GRANT_UPGRADE: { 8531 // Grant runtime permissions for a previously held install permission. 8532 PermissionState permissionState = origPermissions 8533 .getInstallPermissionState(bp.name); 8534 final int flags = permissionState != null ? permissionState.getFlags() : 0; 8535 8536 if (origPermissions.revokeInstallPermission(bp) 8537 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 8538 // We will be transferring the permission flags, so clear them. 8539 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 8540 PackageManager.MASK_PERMISSION_FLAGS, 0); 8541 changedInstallPermission = true; 8542 } 8543 8544 // If the permission is not to be promoted to runtime we ignore it and 8545 // also its other flags as they are not applicable to install permissions. 8546 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 8547 for (int userId : currentUserIds) { 8548 if (permissionsState.grantRuntimePermission(bp, userId) != 8549 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8550 // Transfer the permission flags. 8551 permissionsState.updatePermissionFlags(bp, userId, 8552 flags, flags); 8553 // If we granted the permission, we have to write. 8554 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8555 changedRuntimePermissionUserIds, userId); 8556 } 8557 } 8558 } 8559 } break; 8560 8561 default: { 8562 if (packageOfInterest == null 8563 || packageOfInterest.equals(pkg.packageName)) { 8564 Slog.w(TAG, "Not granting permission " + perm 8565 + " to package " + pkg.packageName 8566 + " because it was previously installed without"); 8567 } 8568 } break; 8569 } 8570 } else { 8571 if (permissionsState.revokeInstallPermission(bp) != 8572 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8573 // Also drop the permission flags. 8574 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 8575 PackageManager.MASK_PERMISSION_FLAGS, 0); 8576 changedInstallPermission = true; 8577 Slog.i(TAG, "Un-granting permission " + perm 8578 + " from package " + pkg.packageName 8579 + " (protectionLevel=" + bp.protectionLevel 8580 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 8581 + ")"); 8582 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 8583 // Don't print warning for app op permissions, since it is fine for them 8584 // not to be granted, there is a UI for the user to decide. 8585 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 8586 Slog.w(TAG, "Not granting permission " + perm 8587 + " to package " + pkg.packageName 8588 + " (protectionLevel=" + bp.protectionLevel 8589 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 8590 + ")"); 8591 } 8592 } 8593 } 8594 } 8595 8596 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 8597 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 8598 // This is the first that we have heard about this package, so the 8599 // permissions we have now selected are fixed until explicitly 8600 // changed. 8601 ps.installPermissionsFixed = true; 8602 } 8603 8604 // Persist the runtime permissions state for users with changes. 8605 for (int userId : changedRuntimePermissionUserIds) { 8606 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 8607 } 8608 8609 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8610 } 8611 8612 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 8613 boolean allowed = false; 8614 final int NP = PackageParser.NEW_PERMISSIONS.length; 8615 for (int ip=0; ip<NP; ip++) { 8616 final PackageParser.NewPermissionInfo npi 8617 = PackageParser.NEW_PERMISSIONS[ip]; 8618 if (npi.name.equals(perm) 8619 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 8620 allowed = true; 8621 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 8622 + pkg.packageName); 8623 break; 8624 } 8625 } 8626 return allowed; 8627 } 8628 8629 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 8630 BasePermission bp, PermissionsState origPermissions) { 8631 boolean allowed; 8632 allowed = (compareSignatures( 8633 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 8634 == PackageManager.SIGNATURE_MATCH) 8635 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 8636 == PackageManager.SIGNATURE_MATCH); 8637 if (!allowed && (bp.protectionLevel 8638 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 8639 if (isSystemApp(pkg)) { 8640 // For updated system applications, a system permission 8641 // is granted only if it had been defined by the original application. 8642 if (pkg.isUpdatedSystemApp()) { 8643 final PackageSetting sysPs = mSettings 8644 .getDisabledSystemPkgLPr(pkg.packageName); 8645 if (sysPs.getPermissionsState().hasInstallPermission(perm)) { 8646 // If the original was granted this permission, we take 8647 // that grant decision as read and propagate it to the 8648 // update. 8649 if (sysPs.isPrivileged()) { 8650 allowed = true; 8651 } 8652 } else { 8653 // The system apk may have been updated with an older 8654 // version of the one on the data partition, but which 8655 // granted a new system permission that it didn't have 8656 // before. In this case we do want to allow the app to 8657 // now get the new permission if the ancestral apk is 8658 // privileged to get it. 8659 if (sysPs.pkg != null && sysPs.isPrivileged()) { 8660 for (int j=0; 8661 j<sysPs.pkg.requestedPermissions.size(); j++) { 8662 if (perm.equals( 8663 sysPs.pkg.requestedPermissions.get(j))) { 8664 allowed = true; 8665 break; 8666 } 8667 } 8668 } 8669 } 8670 } else { 8671 allowed = isPrivilegedApp(pkg); 8672 } 8673 } 8674 } 8675 if (!allowed) { 8676 if (!allowed && (bp.protectionLevel 8677 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 8678 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 8679 // If this was a previously normal/dangerous permission that got moved 8680 // to a system permission as part of the runtime permission redesign, then 8681 // we still want to blindly grant it to old apps. 8682 allowed = true; 8683 } 8684 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 8685 && pkg.packageName.equals(mRequiredInstallerPackage)) { 8686 // If this permission is to be granted to the system installer and 8687 // this app is an installer, then it gets the permission. 8688 allowed = true; 8689 } 8690 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 8691 && pkg.packageName.equals(mRequiredVerifierPackage)) { 8692 // If this permission is to be granted to the system verifier and 8693 // this app is a verifier, then it gets the permission. 8694 allowed = true; 8695 } 8696 if (!allowed && (bp.protectionLevel 8697 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 8698 && isSystemApp(pkg)) { 8699 // Any pre-installed system app is allowed to get this permission. 8700 allowed = true; 8701 } 8702 if (!allowed && (bp.protectionLevel 8703 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 8704 // For development permissions, a development permission 8705 // is granted only if it was already granted. 8706 allowed = origPermissions.hasInstallPermission(perm); 8707 } 8708 } 8709 return allowed; 8710 } 8711 8712 final class ActivityIntentResolver 8713 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 8714 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8715 boolean defaultOnly, int userId) { 8716 if (!sUserManager.exists(userId)) return null; 8717 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8718 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8719 } 8720 8721 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8722 int userId) { 8723 if (!sUserManager.exists(userId)) return null; 8724 mFlags = flags; 8725 return super.queryIntent(intent, resolvedType, 8726 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8727 } 8728 8729 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8730 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 8731 if (!sUserManager.exists(userId)) return null; 8732 if (packageActivities == null) { 8733 return null; 8734 } 8735 mFlags = flags; 8736 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8737 final int N = packageActivities.size(); 8738 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 8739 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 8740 8741 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 8742 for (int i = 0; i < N; ++i) { 8743 intentFilters = packageActivities.get(i).intents; 8744 if (intentFilters != null && intentFilters.size() > 0) { 8745 PackageParser.ActivityIntentInfo[] array = 8746 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 8747 intentFilters.toArray(array); 8748 listCut.add(array); 8749 } 8750 } 8751 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8752 } 8753 8754 public final void addActivity(PackageParser.Activity a, String type) { 8755 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 8756 mActivities.put(a.getComponentName(), a); 8757 if (DEBUG_SHOW_INFO) 8758 Log.v( 8759 TAG, " " + type + " " + 8760 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 8761 if (DEBUG_SHOW_INFO) 8762 Log.v(TAG, " Class=" + a.info.name); 8763 final int NI = a.intents.size(); 8764 for (int j=0; j<NI; j++) { 8765 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 8766 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 8767 intent.setPriority(0); 8768 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 8769 + a.className + " with priority > 0, forcing to 0"); 8770 } 8771 if (DEBUG_SHOW_INFO) { 8772 Log.v(TAG, " IntentFilter:"); 8773 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8774 } 8775 if (!intent.debugCheck()) { 8776 Log.w(TAG, "==> For Activity " + a.info.name); 8777 } 8778 addFilter(intent); 8779 } 8780 } 8781 8782 public final void removeActivity(PackageParser.Activity a, String type) { 8783 mActivities.remove(a.getComponentName()); 8784 if (DEBUG_SHOW_INFO) { 8785 Log.v(TAG, " " + type + " " 8786 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 8787 : a.info.name) + ":"); 8788 Log.v(TAG, " Class=" + a.info.name); 8789 } 8790 final int NI = a.intents.size(); 8791 for (int j=0; j<NI; j++) { 8792 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 8793 if (DEBUG_SHOW_INFO) { 8794 Log.v(TAG, " IntentFilter:"); 8795 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8796 } 8797 removeFilter(intent); 8798 } 8799 } 8800 8801 @Override 8802 protected boolean allowFilterResult( 8803 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 8804 ActivityInfo filterAi = filter.activity.info; 8805 for (int i=dest.size()-1; i>=0; i--) { 8806 ActivityInfo destAi = dest.get(i).activityInfo; 8807 if (destAi.name == filterAi.name 8808 && destAi.packageName == filterAi.packageName) { 8809 return false; 8810 } 8811 } 8812 return true; 8813 } 8814 8815 @Override 8816 protected ActivityIntentInfo[] newArray(int size) { 8817 return new ActivityIntentInfo[size]; 8818 } 8819 8820 @Override 8821 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 8822 if (!sUserManager.exists(userId)) return true; 8823 PackageParser.Package p = filter.activity.owner; 8824 if (p != null) { 8825 PackageSetting ps = (PackageSetting)p.mExtras; 8826 if (ps != null) { 8827 // System apps are never considered stopped for purposes of 8828 // filtering, because there may be no way for the user to 8829 // actually re-launch them. 8830 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 8831 && ps.getStopped(userId); 8832 } 8833 } 8834 return false; 8835 } 8836 8837 @Override 8838 protected boolean isPackageForFilter(String packageName, 8839 PackageParser.ActivityIntentInfo info) { 8840 return packageName.equals(info.activity.owner.packageName); 8841 } 8842 8843 @Override 8844 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 8845 int match, int userId) { 8846 if (!sUserManager.exists(userId)) return null; 8847 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 8848 return null; 8849 } 8850 final PackageParser.Activity activity = info.activity; 8851 if (mSafeMode && (activity.info.applicationInfo.flags 8852 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8853 return null; 8854 } 8855 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 8856 if (ps == null) { 8857 return null; 8858 } 8859 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 8860 ps.readUserState(userId), userId); 8861 if (ai == null) { 8862 return null; 8863 } 8864 final ResolveInfo res = new ResolveInfo(); 8865 res.activityInfo = ai; 8866 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 8867 res.filter = info; 8868 } 8869 if (info != null) { 8870 res.handleAllWebDataURI = info.handleAllWebDataURI(); 8871 } 8872 res.priority = info.getPriority(); 8873 res.preferredOrder = activity.owner.mPreferredOrder; 8874 //System.out.println("Result: " + res.activityInfo.className + 8875 // " = " + res.priority); 8876 res.match = match; 8877 res.isDefault = info.hasDefault; 8878 res.labelRes = info.labelRes; 8879 res.nonLocalizedLabel = info.nonLocalizedLabel; 8880 if (userNeedsBadging(userId)) { 8881 res.noResourceId = true; 8882 } else { 8883 res.icon = info.icon; 8884 } 8885 res.iconResourceId = info.icon; 8886 res.system = res.activityInfo.applicationInfo.isSystemApp(); 8887 return res; 8888 } 8889 8890 @Override 8891 protected void sortResults(List<ResolveInfo> results) { 8892 Collections.sort(results, mResolvePrioritySorter); 8893 } 8894 8895 @Override 8896 protected void dumpFilter(PrintWriter out, String prefix, 8897 PackageParser.ActivityIntentInfo filter) { 8898 out.print(prefix); out.print( 8899 Integer.toHexString(System.identityHashCode(filter.activity))); 8900 out.print(' '); 8901 filter.activity.printComponentShortName(out); 8902 out.print(" filter "); 8903 out.println(Integer.toHexString(System.identityHashCode(filter))); 8904 } 8905 8906 @Override 8907 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 8908 return filter.activity; 8909 } 8910 8911 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8912 PackageParser.Activity activity = (PackageParser.Activity)label; 8913 out.print(prefix); out.print( 8914 Integer.toHexString(System.identityHashCode(activity))); 8915 out.print(' '); 8916 activity.printComponentShortName(out); 8917 if (count > 1) { 8918 out.print(" ("); out.print(count); out.print(" filters)"); 8919 } 8920 out.println(); 8921 } 8922 8923// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8924// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8925// final List<ResolveInfo> retList = Lists.newArrayList(); 8926// while (i.hasNext()) { 8927// final ResolveInfo resolveInfo = i.next(); 8928// if (isEnabledLP(resolveInfo.activityInfo)) { 8929// retList.add(resolveInfo); 8930// } 8931// } 8932// return retList; 8933// } 8934 8935 // Keys are String (activity class name), values are Activity. 8936 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 8937 = new ArrayMap<ComponentName, PackageParser.Activity>(); 8938 private int mFlags; 8939 } 8940 8941 private final class ServiceIntentResolver 8942 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 8943 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8944 boolean defaultOnly, int userId) { 8945 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8946 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8947 } 8948 8949 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8950 int userId) { 8951 if (!sUserManager.exists(userId)) return null; 8952 mFlags = flags; 8953 return super.queryIntent(intent, resolvedType, 8954 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8955 } 8956 8957 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8958 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 8959 if (!sUserManager.exists(userId)) return null; 8960 if (packageServices == null) { 8961 return null; 8962 } 8963 mFlags = flags; 8964 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8965 final int N = packageServices.size(); 8966 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 8967 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 8968 8969 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 8970 for (int i = 0; i < N; ++i) { 8971 intentFilters = packageServices.get(i).intents; 8972 if (intentFilters != null && intentFilters.size() > 0) { 8973 PackageParser.ServiceIntentInfo[] array = 8974 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 8975 intentFilters.toArray(array); 8976 listCut.add(array); 8977 } 8978 } 8979 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8980 } 8981 8982 public final void addService(PackageParser.Service s) { 8983 mServices.put(s.getComponentName(), s); 8984 if (DEBUG_SHOW_INFO) { 8985 Log.v(TAG, " " 8986 + (s.info.nonLocalizedLabel != null 8987 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8988 Log.v(TAG, " Class=" + s.info.name); 8989 } 8990 final int NI = s.intents.size(); 8991 int j; 8992 for (j=0; j<NI; j++) { 8993 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8994 if (DEBUG_SHOW_INFO) { 8995 Log.v(TAG, " IntentFilter:"); 8996 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8997 } 8998 if (!intent.debugCheck()) { 8999 Log.w(TAG, "==> For Service " + s.info.name); 9000 } 9001 addFilter(intent); 9002 } 9003 } 9004 9005 public final void removeService(PackageParser.Service s) { 9006 mServices.remove(s.getComponentName()); 9007 if (DEBUG_SHOW_INFO) { 9008 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 9009 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9010 Log.v(TAG, " Class=" + s.info.name); 9011 } 9012 final int NI = s.intents.size(); 9013 int j; 9014 for (j=0; j<NI; j++) { 9015 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9016 if (DEBUG_SHOW_INFO) { 9017 Log.v(TAG, " IntentFilter:"); 9018 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9019 } 9020 removeFilter(intent); 9021 } 9022 } 9023 9024 @Override 9025 protected boolean allowFilterResult( 9026 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 9027 ServiceInfo filterSi = filter.service.info; 9028 for (int i=dest.size()-1; i>=0; i--) { 9029 ServiceInfo destAi = dest.get(i).serviceInfo; 9030 if (destAi.name == filterSi.name 9031 && destAi.packageName == filterSi.packageName) { 9032 return false; 9033 } 9034 } 9035 return true; 9036 } 9037 9038 @Override 9039 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 9040 return new PackageParser.ServiceIntentInfo[size]; 9041 } 9042 9043 @Override 9044 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 9045 if (!sUserManager.exists(userId)) return true; 9046 PackageParser.Package p = filter.service.owner; 9047 if (p != null) { 9048 PackageSetting ps = (PackageSetting)p.mExtras; 9049 if (ps != null) { 9050 // System apps are never considered stopped for purposes of 9051 // filtering, because there may be no way for the user to 9052 // actually re-launch them. 9053 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9054 && ps.getStopped(userId); 9055 } 9056 } 9057 return false; 9058 } 9059 9060 @Override 9061 protected boolean isPackageForFilter(String packageName, 9062 PackageParser.ServiceIntentInfo info) { 9063 return packageName.equals(info.service.owner.packageName); 9064 } 9065 9066 @Override 9067 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 9068 int match, int userId) { 9069 if (!sUserManager.exists(userId)) return null; 9070 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 9071 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 9072 return null; 9073 } 9074 final PackageParser.Service service = info.service; 9075 if (mSafeMode && (service.info.applicationInfo.flags 9076 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9077 return null; 9078 } 9079 PackageSetting ps = (PackageSetting) service.owner.mExtras; 9080 if (ps == null) { 9081 return null; 9082 } 9083 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 9084 ps.readUserState(userId), userId); 9085 if (si == null) { 9086 return null; 9087 } 9088 final ResolveInfo res = new ResolveInfo(); 9089 res.serviceInfo = si; 9090 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9091 res.filter = filter; 9092 } 9093 res.priority = info.getPriority(); 9094 res.preferredOrder = service.owner.mPreferredOrder; 9095 res.match = match; 9096 res.isDefault = info.hasDefault; 9097 res.labelRes = info.labelRes; 9098 res.nonLocalizedLabel = info.nonLocalizedLabel; 9099 res.icon = info.icon; 9100 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 9101 return res; 9102 } 9103 9104 @Override 9105 protected void sortResults(List<ResolveInfo> results) { 9106 Collections.sort(results, mResolvePrioritySorter); 9107 } 9108 9109 @Override 9110 protected void dumpFilter(PrintWriter out, String prefix, 9111 PackageParser.ServiceIntentInfo filter) { 9112 out.print(prefix); out.print( 9113 Integer.toHexString(System.identityHashCode(filter.service))); 9114 out.print(' '); 9115 filter.service.printComponentShortName(out); 9116 out.print(" filter "); 9117 out.println(Integer.toHexString(System.identityHashCode(filter))); 9118 } 9119 9120 @Override 9121 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 9122 return filter.service; 9123 } 9124 9125 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9126 PackageParser.Service service = (PackageParser.Service)label; 9127 out.print(prefix); out.print( 9128 Integer.toHexString(System.identityHashCode(service))); 9129 out.print(' '); 9130 service.printComponentShortName(out); 9131 if (count > 1) { 9132 out.print(" ("); out.print(count); out.print(" filters)"); 9133 } 9134 out.println(); 9135 } 9136 9137// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9138// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9139// final List<ResolveInfo> retList = Lists.newArrayList(); 9140// while (i.hasNext()) { 9141// final ResolveInfo resolveInfo = (ResolveInfo) i; 9142// if (isEnabledLP(resolveInfo.serviceInfo)) { 9143// retList.add(resolveInfo); 9144// } 9145// } 9146// return retList; 9147// } 9148 9149 // Keys are String (activity class name), values are Activity. 9150 private final ArrayMap<ComponentName, PackageParser.Service> mServices 9151 = new ArrayMap<ComponentName, PackageParser.Service>(); 9152 private int mFlags; 9153 }; 9154 9155 private final class ProviderIntentResolver 9156 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 9157 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9158 boolean defaultOnly, int userId) { 9159 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9160 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9161 } 9162 9163 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9164 int userId) { 9165 if (!sUserManager.exists(userId)) 9166 return null; 9167 mFlags = flags; 9168 return super.queryIntent(intent, resolvedType, 9169 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9170 } 9171 9172 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9173 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 9174 if (!sUserManager.exists(userId)) 9175 return null; 9176 if (packageProviders == null) { 9177 return null; 9178 } 9179 mFlags = flags; 9180 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 9181 final int N = packageProviders.size(); 9182 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 9183 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 9184 9185 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 9186 for (int i = 0; i < N; ++i) { 9187 intentFilters = packageProviders.get(i).intents; 9188 if (intentFilters != null && intentFilters.size() > 0) { 9189 PackageParser.ProviderIntentInfo[] array = 9190 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 9191 intentFilters.toArray(array); 9192 listCut.add(array); 9193 } 9194 } 9195 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9196 } 9197 9198 public final void addProvider(PackageParser.Provider p) { 9199 if (mProviders.containsKey(p.getComponentName())) { 9200 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 9201 return; 9202 } 9203 9204 mProviders.put(p.getComponentName(), p); 9205 if (DEBUG_SHOW_INFO) { 9206 Log.v(TAG, " " 9207 + (p.info.nonLocalizedLabel != null 9208 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 9209 Log.v(TAG, " Class=" + p.info.name); 9210 } 9211 final int NI = p.intents.size(); 9212 int j; 9213 for (j = 0; j < NI; j++) { 9214 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 9215 if (DEBUG_SHOW_INFO) { 9216 Log.v(TAG, " IntentFilter:"); 9217 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9218 } 9219 if (!intent.debugCheck()) { 9220 Log.w(TAG, "==> For Provider " + p.info.name); 9221 } 9222 addFilter(intent); 9223 } 9224 } 9225 9226 public final void removeProvider(PackageParser.Provider p) { 9227 mProviders.remove(p.getComponentName()); 9228 if (DEBUG_SHOW_INFO) { 9229 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 9230 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 9231 Log.v(TAG, " Class=" + p.info.name); 9232 } 9233 final int NI = p.intents.size(); 9234 int j; 9235 for (j = 0; j < NI; j++) { 9236 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 9237 if (DEBUG_SHOW_INFO) { 9238 Log.v(TAG, " IntentFilter:"); 9239 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9240 } 9241 removeFilter(intent); 9242 } 9243 } 9244 9245 @Override 9246 protected boolean allowFilterResult( 9247 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 9248 ProviderInfo filterPi = filter.provider.info; 9249 for (int i = dest.size() - 1; i >= 0; i--) { 9250 ProviderInfo destPi = dest.get(i).providerInfo; 9251 if (destPi.name == filterPi.name 9252 && destPi.packageName == filterPi.packageName) { 9253 return false; 9254 } 9255 } 9256 return true; 9257 } 9258 9259 @Override 9260 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 9261 return new PackageParser.ProviderIntentInfo[size]; 9262 } 9263 9264 @Override 9265 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 9266 if (!sUserManager.exists(userId)) 9267 return true; 9268 PackageParser.Package p = filter.provider.owner; 9269 if (p != null) { 9270 PackageSetting ps = (PackageSetting) p.mExtras; 9271 if (ps != null) { 9272 // System apps are never considered stopped for purposes of 9273 // filtering, because there may be no way for the user to 9274 // actually re-launch them. 9275 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9276 && ps.getStopped(userId); 9277 } 9278 } 9279 return false; 9280 } 9281 9282 @Override 9283 protected boolean isPackageForFilter(String packageName, 9284 PackageParser.ProviderIntentInfo info) { 9285 return packageName.equals(info.provider.owner.packageName); 9286 } 9287 9288 @Override 9289 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 9290 int match, int userId) { 9291 if (!sUserManager.exists(userId)) 9292 return null; 9293 final PackageParser.ProviderIntentInfo info = filter; 9294 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 9295 return null; 9296 } 9297 final PackageParser.Provider provider = info.provider; 9298 if (mSafeMode && (provider.info.applicationInfo.flags 9299 & ApplicationInfo.FLAG_SYSTEM) == 0) { 9300 return null; 9301 } 9302 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 9303 if (ps == null) { 9304 return null; 9305 } 9306 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 9307 ps.readUserState(userId), userId); 9308 if (pi == null) { 9309 return null; 9310 } 9311 final ResolveInfo res = new ResolveInfo(); 9312 res.providerInfo = pi; 9313 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 9314 res.filter = filter; 9315 } 9316 res.priority = info.getPriority(); 9317 res.preferredOrder = provider.owner.mPreferredOrder; 9318 res.match = match; 9319 res.isDefault = info.hasDefault; 9320 res.labelRes = info.labelRes; 9321 res.nonLocalizedLabel = info.nonLocalizedLabel; 9322 res.icon = info.icon; 9323 res.system = res.providerInfo.applicationInfo.isSystemApp(); 9324 return res; 9325 } 9326 9327 @Override 9328 protected void sortResults(List<ResolveInfo> results) { 9329 Collections.sort(results, mResolvePrioritySorter); 9330 } 9331 9332 @Override 9333 protected void dumpFilter(PrintWriter out, String prefix, 9334 PackageParser.ProviderIntentInfo filter) { 9335 out.print(prefix); 9336 out.print( 9337 Integer.toHexString(System.identityHashCode(filter.provider))); 9338 out.print(' '); 9339 filter.provider.printComponentShortName(out); 9340 out.print(" filter "); 9341 out.println(Integer.toHexString(System.identityHashCode(filter))); 9342 } 9343 9344 @Override 9345 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 9346 return filter.provider; 9347 } 9348 9349 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9350 PackageParser.Provider provider = (PackageParser.Provider)label; 9351 out.print(prefix); out.print( 9352 Integer.toHexString(System.identityHashCode(provider))); 9353 out.print(' '); 9354 provider.printComponentShortName(out); 9355 if (count > 1) { 9356 out.print(" ("); out.print(count); out.print(" filters)"); 9357 } 9358 out.println(); 9359 } 9360 9361 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 9362 = new ArrayMap<ComponentName, PackageParser.Provider>(); 9363 private int mFlags; 9364 }; 9365 9366 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 9367 new Comparator<ResolveInfo>() { 9368 public int compare(ResolveInfo r1, ResolveInfo r2) { 9369 int v1 = r1.priority; 9370 int v2 = r2.priority; 9371 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 9372 if (v1 != v2) { 9373 return (v1 > v2) ? -1 : 1; 9374 } 9375 v1 = r1.preferredOrder; 9376 v2 = r2.preferredOrder; 9377 if (v1 != v2) { 9378 return (v1 > v2) ? -1 : 1; 9379 } 9380 if (r1.isDefault != r2.isDefault) { 9381 return r1.isDefault ? -1 : 1; 9382 } 9383 v1 = r1.match; 9384 v2 = r2.match; 9385 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 9386 if (v1 != v2) { 9387 return (v1 > v2) ? -1 : 1; 9388 } 9389 if (r1.system != r2.system) { 9390 return r1.system ? -1 : 1; 9391 } 9392 return 0; 9393 } 9394 }; 9395 9396 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 9397 new Comparator<ProviderInfo>() { 9398 public int compare(ProviderInfo p1, ProviderInfo p2) { 9399 final int v1 = p1.initOrder; 9400 final int v2 = p2.initOrder; 9401 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 9402 } 9403 }; 9404 9405 final void sendPackageBroadcast(final String action, final String pkg, 9406 final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver, 9407 final int[] userIds) { 9408 mHandler.post(new Runnable() { 9409 @Override 9410 public void run() { 9411 try { 9412 final IActivityManager am = ActivityManagerNative.getDefault(); 9413 if (am == null) return; 9414 final int[] resolvedUserIds; 9415 if (userIds == null) { 9416 resolvedUserIds = am.getRunningUserIds(); 9417 } else { 9418 resolvedUserIds = userIds; 9419 } 9420 for (int id : resolvedUserIds) { 9421 final Intent intent = new Intent(action, 9422 pkg != null ? Uri.fromParts("package", pkg, null) : null); 9423 if (extras != null) { 9424 intent.putExtras(extras); 9425 } 9426 if (targetPkg != null) { 9427 intent.setPackage(targetPkg); 9428 } 9429 // Modify the UID when posting to other users 9430 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 9431 if (uid > 0 && UserHandle.getUserId(uid) != id) { 9432 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 9433 intent.putExtra(Intent.EXTRA_UID, uid); 9434 } 9435 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 9436 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 9437 if (DEBUG_BROADCASTS) { 9438 RuntimeException here = new RuntimeException("here"); 9439 here.fillInStackTrace(); 9440 Slog.d(TAG, "Sending to user " + id + ": " 9441 + intent.toShortString(false, true, false, false) 9442 + " " + intent.getExtras(), here); 9443 } 9444 am.broadcastIntent(null, intent, null, finishedReceiver, 9445 0, null, null, null, android.app.AppOpsManager.OP_NONE, 9446 null, finishedReceiver != null, false, id); 9447 } 9448 } catch (RemoteException ex) { 9449 } 9450 } 9451 }); 9452 } 9453 9454 /** 9455 * Check if the external storage media is available. This is true if there 9456 * is a mounted external storage medium or if the external storage is 9457 * emulated. 9458 */ 9459 private boolean isExternalMediaAvailable() { 9460 return mMediaMounted || Environment.isExternalStorageEmulated(); 9461 } 9462 9463 @Override 9464 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 9465 // writer 9466 synchronized (mPackages) { 9467 if (!isExternalMediaAvailable()) { 9468 // If the external storage is no longer mounted at this point, 9469 // the caller may not have been able to delete all of this 9470 // packages files and can not delete any more. Bail. 9471 return null; 9472 } 9473 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 9474 if (lastPackage != null) { 9475 pkgs.remove(lastPackage); 9476 } 9477 if (pkgs.size() > 0) { 9478 return pkgs.get(0); 9479 } 9480 } 9481 return null; 9482 } 9483 9484 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 9485 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 9486 userId, andCode ? 1 : 0, packageName); 9487 if (mSystemReady) { 9488 msg.sendToTarget(); 9489 } else { 9490 if (mPostSystemReadyMessages == null) { 9491 mPostSystemReadyMessages = new ArrayList<>(); 9492 } 9493 mPostSystemReadyMessages.add(msg); 9494 } 9495 } 9496 9497 void startCleaningPackages() { 9498 // reader 9499 synchronized (mPackages) { 9500 if (!isExternalMediaAvailable()) { 9501 return; 9502 } 9503 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 9504 return; 9505 } 9506 } 9507 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 9508 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 9509 IActivityManager am = ActivityManagerNative.getDefault(); 9510 if (am != null) { 9511 try { 9512 am.startService(null, intent, null, mContext.getOpPackageName(), 9513 UserHandle.USER_OWNER); 9514 } catch (RemoteException e) { 9515 } 9516 } 9517 } 9518 9519 @Override 9520 public void installPackage(String originPath, IPackageInstallObserver2 observer, 9521 int installFlags, String installerPackageName, VerificationParams verificationParams, 9522 String packageAbiOverride) { 9523 installPackageAsUser(originPath, observer, installFlags, installerPackageName, 9524 verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); 9525 } 9526 9527 @Override 9528 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 9529 int installFlags, String installerPackageName, VerificationParams verificationParams, 9530 String packageAbiOverride, int userId) { 9531 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 9532 9533 final int callingUid = Binder.getCallingUid(); 9534 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 9535 9536 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 9537 try { 9538 if (observer != null) { 9539 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 9540 } 9541 } catch (RemoteException re) { 9542 } 9543 return; 9544 } 9545 9546 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 9547 installFlags |= PackageManager.INSTALL_FROM_ADB; 9548 9549 } else { 9550 // Caller holds INSTALL_PACKAGES permission, so we're less strict 9551 // about installerPackageName. 9552 9553 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 9554 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 9555 } 9556 9557 UserHandle user; 9558 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 9559 user = UserHandle.ALL; 9560 } else { 9561 user = new UserHandle(userId); 9562 } 9563 9564 // Only system components can circumvent runtime permissions when installing. 9565 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 9566 && mContext.checkCallingOrSelfPermission(Manifest.permission 9567 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 9568 throw new SecurityException("You need the " 9569 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 9570 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 9571 } 9572 9573 verificationParams.setInstallerUid(callingUid); 9574 9575 final File originFile = new File(originPath); 9576 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 9577 9578 final Message msg = mHandler.obtainMessage(INIT_COPY); 9579 msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName, 9580 null, verificationParams, user, packageAbiOverride, null); 9581 mHandler.sendMessage(msg); 9582 } 9583 9584 void installStage(String packageName, File stagedDir, String stagedCid, 9585 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, 9586 String installerPackageName, int installerUid, UserHandle user) { 9587 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 9588 params.referrerUri, installerUid, null); 9589 verifParams.setInstallerUid(installerUid); 9590 9591 final OriginInfo origin; 9592 if (stagedDir != null) { 9593 origin = OriginInfo.fromStagedFile(stagedDir); 9594 } else { 9595 origin = OriginInfo.fromStagedContainer(stagedCid); 9596 } 9597 9598 final Message msg = mHandler.obtainMessage(INIT_COPY); 9599 msg.obj = new InstallParams(origin, null, observer, params.installFlags, 9600 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride, 9601 params.grantedRuntimePermissions); 9602 9603 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 9604 System.identityHashCode(msg.obj)); 9605 9606 mHandler.sendMessage(msg); 9607 } 9608 9609 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 9610 Bundle extras = new Bundle(1); 9611 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 9612 9613 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 9614 packageName, extras, null, null, new int[] {userId}); 9615 try { 9616 IActivityManager am = ActivityManagerNative.getDefault(); 9617 final boolean isSystem = 9618 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 9619 if (isSystem && am.isUserRunning(userId, false)) { 9620 // The just-installed/enabled app is bundled on the system, so presumed 9621 // to be able to run automatically without needing an explicit launch. 9622 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 9623 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 9624 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 9625 .setPackage(packageName); 9626 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 9627 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 9628 } 9629 } catch (RemoteException e) { 9630 // shouldn't happen 9631 Slog.w(TAG, "Unable to bootstrap installed package", e); 9632 } 9633 } 9634 9635 @Override 9636 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 9637 int userId) { 9638 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9639 PackageSetting pkgSetting; 9640 final int uid = Binder.getCallingUid(); 9641 enforceCrossUserPermission(uid, userId, true, true, 9642 "setApplicationHiddenSetting for user " + userId); 9643 9644 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 9645 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 9646 return false; 9647 } 9648 9649 long callingId = Binder.clearCallingIdentity(); 9650 try { 9651 boolean sendAdded = false; 9652 boolean sendRemoved = false; 9653 // writer 9654 synchronized (mPackages) { 9655 pkgSetting = mSettings.mPackages.get(packageName); 9656 if (pkgSetting == null) { 9657 return false; 9658 } 9659 if (pkgSetting.getHidden(userId) != hidden) { 9660 pkgSetting.setHidden(hidden, userId); 9661 mSettings.writePackageRestrictionsLPr(userId); 9662 if (hidden) { 9663 sendRemoved = true; 9664 } else { 9665 sendAdded = true; 9666 } 9667 } 9668 } 9669 if (sendAdded) { 9670 sendPackageAddedForUser(packageName, pkgSetting, userId); 9671 return true; 9672 } 9673 if (sendRemoved) { 9674 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 9675 "hiding pkg"); 9676 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 9677 return true; 9678 } 9679 } finally { 9680 Binder.restoreCallingIdentity(callingId); 9681 } 9682 return false; 9683 } 9684 9685 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 9686 int userId) { 9687 final PackageRemovedInfo info = new PackageRemovedInfo(); 9688 info.removedPackage = packageName; 9689 info.removedUsers = new int[] {userId}; 9690 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 9691 info.sendBroadcast(false, false, false); 9692 } 9693 9694 /** 9695 * Returns true if application is not found or there was an error. Otherwise it returns 9696 * the hidden state of the package for the given user. 9697 */ 9698 @Override 9699 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 9700 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9701 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 9702 false, "getApplicationHidden for user " + userId); 9703 PackageSetting pkgSetting; 9704 long callingId = Binder.clearCallingIdentity(); 9705 try { 9706 // writer 9707 synchronized (mPackages) { 9708 pkgSetting = mSettings.mPackages.get(packageName); 9709 if (pkgSetting == null) { 9710 return true; 9711 } 9712 return pkgSetting.getHidden(userId); 9713 } 9714 } finally { 9715 Binder.restoreCallingIdentity(callingId); 9716 } 9717 } 9718 9719 /** 9720 * @hide 9721 */ 9722 @Override 9723 public int installExistingPackageAsUser(String packageName, int userId) { 9724 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 9725 null); 9726 PackageSetting pkgSetting; 9727 final int uid = Binder.getCallingUid(); 9728 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 9729 + userId); 9730 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 9731 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 9732 } 9733 9734 long callingId = Binder.clearCallingIdentity(); 9735 try { 9736 boolean sendAdded = false; 9737 9738 // writer 9739 synchronized (mPackages) { 9740 pkgSetting = mSettings.mPackages.get(packageName); 9741 if (pkgSetting == null) { 9742 return PackageManager.INSTALL_FAILED_INVALID_URI; 9743 } 9744 if (!pkgSetting.getInstalled(userId)) { 9745 pkgSetting.setInstalled(true, userId); 9746 pkgSetting.setHidden(false, userId); 9747 mSettings.writePackageRestrictionsLPr(userId); 9748 sendAdded = true; 9749 } 9750 } 9751 9752 if (sendAdded) { 9753 sendPackageAddedForUser(packageName, pkgSetting, userId); 9754 } 9755 } finally { 9756 Binder.restoreCallingIdentity(callingId); 9757 } 9758 9759 return PackageManager.INSTALL_SUCCEEDED; 9760 } 9761 9762 boolean isUserRestricted(int userId, String restrictionKey) { 9763 Bundle restrictions = sUserManager.getUserRestrictions(userId); 9764 if (restrictions.getBoolean(restrictionKey, false)) { 9765 Log.w(TAG, "User is restricted: " + restrictionKey); 9766 return true; 9767 } 9768 return false; 9769 } 9770 9771 @Override 9772 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 9773 mContext.enforceCallingOrSelfPermission( 9774 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9775 "Only package verification agents can verify applications"); 9776 9777 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 9778 final PackageVerificationResponse response = new PackageVerificationResponse( 9779 verificationCode, Binder.getCallingUid()); 9780 msg.arg1 = id; 9781 msg.obj = response; 9782 mHandler.sendMessage(msg); 9783 } 9784 9785 @Override 9786 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 9787 long millisecondsToDelay) { 9788 mContext.enforceCallingOrSelfPermission( 9789 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9790 "Only package verification agents can extend verification timeouts"); 9791 9792 final PackageVerificationState state = mPendingVerification.get(id); 9793 final PackageVerificationResponse response = new PackageVerificationResponse( 9794 verificationCodeAtTimeout, Binder.getCallingUid()); 9795 9796 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 9797 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 9798 } 9799 if (millisecondsToDelay < 0) { 9800 millisecondsToDelay = 0; 9801 } 9802 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 9803 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 9804 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 9805 } 9806 9807 if ((state != null) && !state.timeoutExtended()) { 9808 state.extendTimeout(); 9809 9810 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 9811 msg.arg1 = id; 9812 msg.obj = response; 9813 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 9814 } 9815 } 9816 9817 private void broadcastPackageVerified(int verificationId, Uri packageUri, 9818 int verificationCode, UserHandle user) { 9819 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 9820 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 9821 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 9822 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 9823 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 9824 9825 mContext.sendBroadcastAsUser(intent, user, 9826 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 9827 } 9828 9829 private ComponentName matchComponentForVerifier(String packageName, 9830 List<ResolveInfo> receivers) { 9831 ActivityInfo targetReceiver = null; 9832 9833 final int NR = receivers.size(); 9834 for (int i = 0; i < NR; i++) { 9835 final ResolveInfo info = receivers.get(i); 9836 if (info.activityInfo == null) { 9837 continue; 9838 } 9839 9840 if (packageName.equals(info.activityInfo.packageName)) { 9841 targetReceiver = info.activityInfo; 9842 break; 9843 } 9844 } 9845 9846 if (targetReceiver == null) { 9847 return null; 9848 } 9849 9850 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 9851 } 9852 9853 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 9854 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 9855 if (pkgInfo.verifiers.length == 0) { 9856 return null; 9857 } 9858 9859 final int N = pkgInfo.verifiers.length; 9860 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 9861 for (int i = 0; i < N; i++) { 9862 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 9863 9864 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 9865 receivers); 9866 if (comp == null) { 9867 continue; 9868 } 9869 9870 final int verifierUid = getUidForVerifier(verifierInfo); 9871 if (verifierUid == -1) { 9872 continue; 9873 } 9874 9875 if (DEBUG_VERIFY) { 9876 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 9877 + " with the correct signature"); 9878 } 9879 sufficientVerifiers.add(comp); 9880 verificationState.addSufficientVerifier(verifierUid); 9881 } 9882 9883 return sufficientVerifiers; 9884 } 9885 9886 private int getUidForVerifier(VerifierInfo verifierInfo) { 9887 synchronized (mPackages) { 9888 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 9889 if (pkg == null) { 9890 return -1; 9891 } else if (pkg.mSignatures.length != 1) { 9892 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 9893 + " has more than one signature; ignoring"); 9894 return -1; 9895 } 9896 9897 /* 9898 * If the public key of the package's signature does not match 9899 * our expected public key, then this is a different package and 9900 * we should skip. 9901 */ 9902 9903 final byte[] expectedPublicKey; 9904 try { 9905 final Signature verifierSig = pkg.mSignatures[0]; 9906 final PublicKey publicKey = verifierSig.getPublicKey(); 9907 expectedPublicKey = publicKey.getEncoded(); 9908 } catch (CertificateException e) { 9909 return -1; 9910 } 9911 9912 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 9913 9914 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 9915 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 9916 + " does not have the expected public key; ignoring"); 9917 return -1; 9918 } 9919 9920 return pkg.applicationInfo.uid; 9921 } 9922 } 9923 9924 @Override 9925 public void finishPackageInstall(int token) { 9926 enforceSystemOrRoot("Only the system is allowed to finish installs"); 9927 9928 if (DEBUG_INSTALL) { 9929 Slog.v(TAG, "BM finishing package install for " + token); 9930 } 9931 9932 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9933 mHandler.sendMessage(msg); 9934 } 9935 9936 /** 9937 * Get the verification agent timeout. 9938 * 9939 * @return verification timeout in milliseconds 9940 */ 9941 private long getVerificationTimeout() { 9942 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 9943 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 9944 DEFAULT_VERIFICATION_TIMEOUT); 9945 } 9946 9947 /** 9948 * Get the default verification agent response code. 9949 * 9950 * @return default verification response code 9951 */ 9952 private int getDefaultVerificationResponse() { 9953 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9954 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 9955 DEFAULT_VERIFICATION_RESPONSE); 9956 } 9957 9958 /** 9959 * Check whether or not package verification has been enabled. 9960 * 9961 * @return true if verification should be performed 9962 */ 9963 private boolean isVerificationEnabled(int userId, int installFlags) { 9964 if (!DEFAULT_VERIFY_ENABLE) { 9965 return false; 9966 } 9967 9968 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 9969 9970 // Check if installing from ADB 9971 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 9972 // Do not run verification in a test harness environment 9973 if (ActivityManager.isRunningInTestHarness()) { 9974 return false; 9975 } 9976 if (ensureVerifyAppsEnabled) { 9977 return true; 9978 } 9979 // Check if the developer does not want package verification for ADB installs 9980 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9981 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 9982 return false; 9983 } 9984 } 9985 9986 if (ensureVerifyAppsEnabled) { 9987 return true; 9988 } 9989 9990 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9991 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 9992 } 9993 9994 @Override 9995 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 9996 throws RemoteException { 9997 mContext.enforceCallingOrSelfPermission( 9998 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 9999 "Only intentfilter verification agents can verify applications"); 10000 10001 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 10002 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 10003 Binder.getCallingUid(), verificationCode, failedDomains); 10004 msg.arg1 = id; 10005 msg.obj = response; 10006 mHandler.sendMessage(msg); 10007 } 10008 10009 @Override 10010 public int getIntentVerificationStatus(String packageName, int userId) { 10011 synchronized (mPackages) { 10012 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 10013 } 10014 } 10015 10016 @Override 10017 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 10018 mContext.enforceCallingOrSelfPermission( 10019 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10020 10021 boolean result = false; 10022 synchronized (mPackages) { 10023 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 10024 } 10025 if (result) { 10026 scheduleWritePackageRestrictionsLocked(userId); 10027 } 10028 return result; 10029 } 10030 10031 @Override 10032 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 10033 synchronized (mPackages) { 10034 return mSettings.getIntentFilterVerificationsLPr(packageName); 10035 } 10036 } 10037 10038 @Override 10039 public List<IntentFilter> getAllIntentFilters(String packageName) { 10040 if (TextUtils.isEmpty(packageName)) { 10041 return Collections.<IntentFilter>emptyList(); 10042 } 10043 synchronized (mPackages) { 10044 PackageParser.Package pkg = mPackages.get(packageName); 10045 if (pkg == null || pkg.activities == null) { 10046 return Collections.<IntentFilter>emptyList(); 10047 } 10048 final int count = pkg.activities.size(); 10049 ArrayList<IntentFilter> result = new ArrayList<>(); 10050 for (int n=0; n<count; n++) { 10051 PackageParser.Activity activity = pkg.activities.get(n); 10052 if (activity.intents != null || activity.intents.size() > 0) { 10053 result.addAll(activity.intents); 10054 } 10055 } 10056 return result; 10057 } 10058 } 10059 10060 @Override 10061 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 10062 mContext.enforceCallingOrSelfPermission( 10063 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10064 10065 synchronized (mPackages) { 10066 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 10067 if (packageName != null) { 10068 result |= updateIntentVerificationStatus(packageName, 10069 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 10070 userId); 10071 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 10072 packageName, userId); 10073 } 10074 return result; 10075 } 10076 } 10077 10078 @Override 10079 public String getDefaultBrowserPackageName(int userId) { 10080 synchronized (mPackages) { 10081 return mSettings.getDefaultBrowserPackageNameLPw(userId); 10082 } 10083 } 10084 10085 /** 10086 * Get the "allow unknown sources" setting. 10087 * 10088 * @return the current "allow unknown sources" setting 10089 */ 10090 private int getUnknownSourcesSettings() { 10091 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10092 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 10093 -1); 10094 } 10095 10096 @Override 10097 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 10098 final int uid = Binder.getCallingUid(); 10099 // writer 10100 synchronized (mPackages) { 10101 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 10102 if (targetPackageSetting == null) { 10103 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 10104 } 10105 10106 PackageSetting installerPackageSetting; 10107 if (installerPackageName != null) { 10108 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 10109 if (installerPackageSetting == null) { 10110 throw new IllegalArgumentException("Unknown installer package: " 10111 + installerPackageName); 10112 } 10113 } else { 10114 installerPackageSetting = null; 10115 } 10116 10117 Signature[] callerSignature; 10118 Object obj = mSettings.getUserIdLPr(uid); 10119 if (obj != null) { 10120 if (obj instanceof SharedUserSetting) { 10121 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 10122 } else if (obj instanceof PackageSetting) { 10123 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 10124 } else { 10125 throw new SecurityException("Bad object " + obj + " for uid " + uid); 10126 } 10127 } else { 10128 throw new SecurityException("Unknown calling uid " + uid); 10129 } 10130 10131 // Verify: can't set installerPackageName to a package that is 10132 // not signed with the same cert as the caller. 10133 if (installerPackageSetting != null) { 10134 if (compareSignatures(callerSignature, 10135 installerPackageSetting.signatures.mSignatures) 10136 != PackageManager.SIGNATURE_MATCH) { 10137 throw new SecurityException( 10138 "Caller does not have same cert as new installer package " 10139 + installerPackageName); 10140 } 10141 } 10142 10143 // Verify: if target already has an installer package, it must 10144 // be signed with the same cert as the caller. 10145 if (targetPackageSetting.installerPackageName != null) { 10146 PackageSetting setting = mSettings.mPackages.get( 10147 targetPackageSetting.installerPackageName); 10148 // If the currently set package isn't valid, then it's always 10149 // okay to change it. 10150 if (setting != null) { 10151 if (compareSignatures(callerSignature, 10152 setting.signatures.mSignatures) 10153 != PackageManager.SIGNATURE_MATCH) { 10154 throw new SecurityException( 10155 "Caller does not have same cert as old installer package " 10156 + targetPackageSetting.installerPackageName); 10157 } 10158 } 10159 } 10160 10161 // Okay! 10162 targetPackageSetting.installerPackageName = installerPackageName; 10163 scheduleWriteSettingsLocked(); 10164 } 10165 } 10166 10167 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 10168 // Queue up an async operation since the package installation may take a little while. 10169 mHandler.post(new Runnable() { 10170 public void run() { 10171 mHandler.removeCallbacks(this); 10172 // Result object to be returned 10173 PackageInstalledInfo res = new PackageInstalledInfo(); 10174 res.returnCode = currentStatus; 10175 res.uid = -1; 10176 res.pkg = null; 10177 res.removedInfo = new PackageRemovedInfo(); 10178 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 10179 args.doPreInstall(res.returnCode); 10180 synchronized (mInstallLock) { 10181 installPackageTracedLI(args, res); 10182 } 10183 args.doPostInstall(res.returnCode, res.uid); 10184 } 10185 10186 // A restore should be performed at this point if (a) the install 10187 // succeeded, (b) the operation is not an update, and (c) the new 10188 // package has not opted out of backup participation. 10189 final boolean update = res.removedInfo.removedPackage != null; 10190 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 10191 boolean doRestore = !update 10192 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 10193 10194 // Set up the post-install work request bookkeeping. This will be used 10195 // and cleaned up by the post-install event handling regardless of whether 10196 // there's a restore pass performed. Token values are >= 1. 10197 int token; 10198 if (mNextInstallToken < 0) mNextInstallToken = 1; 10199 token = mNextInstallToken++; 10200 10201 PostInstallData data = new PostInstallData(args, res); 10202 mRunningInstalls.put(token, data); 10203 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 10204 10205 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 10206 // Pass responsibility to the Backup Manager. It will perform a 10207 // restore if appropriate, then pass responsibility back to the 10208 // Package Manager to run the post-install observer callbacks 10209 // and broadcasts. 10210 IBackupManager bm = IBackupManager.Stub.asInterface( 10211 ServiceManager.getService(Context.BACKUP_SERVICE)); 10212 if (bm != null) { 10213 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 10214 + " to BM for possible restore"); 10215 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 10216 try { 10217 if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { 10218 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 10219 } else { 10220 doRestore = false; 10221 } 10222 } catch (RemoteException e) { 10223 // can't happen; the backup manager is local 10224 } catch (Exception e) { 10225 Slog.e(TAG, "Exception trying to enqueue restore", e); 10226 doRestore = false; 10227 } finally { 10228 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 10229 } 10230 } else { 10231 Slog.e(TAG, "Backup Manager not found!"); 10232 doRestore = false; 10233 } 10234 } 10235 10236 if (!doRestore) { 10237 // No restore possible, or the Backup Manager was mysteriously not 10238 // available -- just fire the post-install work request directly. 10239 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 10240 10241 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 10242 10243 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 10244 mHandler.sendMessage(msg); 10245 } 10246 } 10247 }); 10248 } 10249 10250 private abstract class HandlerParams { 10251 private static final int MAX_RETRIES = 4; 10252 10253 /** 10254 * Number of times startCopy() has been attempted and had a non-fatal 10255 * error. 10256 */ 10257 private int mRetries = 0; 10258 10259 /** User handle for the user requesting the information or installation. */ 10260 private final UserHandle mUser; 10261 10262 HandlerParams(UserHandle user) { 10263 mUser = user; 10264 } 10265 10266 UserHandle getUser() { 10267 return mUser; 10268 } 10269 10270 final boolean startCopy() { 10271 boolean res; 10272 try { 10273 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 10274 10275 if (++mRetries > MAX_RETRIES) { 10276 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 10277 mHandler.sendEmptyMessage(MCS_GIVE_UP); 10278 handleServiceError(); 10279 return false; 10280 } else { 10281 handleStartCopy(); 10282 res = true; 10283 } 10284 } catch (RemoteException e) { 10285 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 10286 mHandler.sendEmptyMessage(MCS_RECONNECT); 10287 res = false; 10288 } 10289 handleReturnCode(); 10290 return res; 10291 } 10292 10293 final void serviceError() { 10294 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 10295 handleServiceError(); 10296 handleReturnCode(); 10297 } 10298 10299 abstract void handleStartCopy() throws RemoteException; 10300 abstract void handleServiceError(); 10301 abstract void handleReturnCode(); 10302 } 10303 10304 class MeasureParams extends HandlerParams { 10305 private final PackageStats mStats; 10306 private boolean mSuccess; 10307 10308 private final IPackageStatsObserver mObserver; 10309 10310 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 10311 super(new UserHandle(stats.userHandle)); 10312 mObserver = observer; 10313 mStats = stats; 10314 } 10315 10316 @Override 10317 public String toString() { 10318 return "MeasureParams{" 10319 + Integer.toHexString(System.identityHashCode(this)) 10320 + " " + mStats.packageName + "}"; 10321 } 10322 10323 @Override 10324 void handleStartCopy() throws RemoteException { 10325 synchronized (mInstallLock) { 10326 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 10327 } 10328 10329 if (mSuccess) { 10330 final boolean mounted; 10331 if (Environment.isExternalStorageEmulated()) { 10332 mounted = true; 10333 } else { 10334 final String status = Environment.getExternalStorageState(); 10335 mounted = (Environment.MEDIA_MOUNTED.equals(status) 10336 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 10337 } 10338 10339 if (mounted) { 10340 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 10341 10342 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 10343 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 10344 10345 mStats.externalDataSize = calculateDirectorySize(mContainerService, 10346 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 10347 10348 // Always subtract cache size, since it's a subdirectory 10349 mStats.externalDataSize -= mStats.externalCacheSize; 10350 10351 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 10352 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 10353 10354 mStats.externalObbSize = calculateDirectorySize(mContainerService, 10355 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 10356 } 10357 } 10358 } 10359 10360 @Override 10361 void handleReturnCode() { 10362 if (mObserver != null) { 10363 try { 10364 mObserver.onGetStatsCompleted(mStats, mSuccess); 10365 } catch (RemoteException e) { 10366 Slog.i(TAG, "Observer no longer exists."); 10367 } 10368 } 10369 } 10370 10371 @Override 10372 void handleServiceError() { 10373 Slog.e(TAG, "Could not measure application " + mStats.packageName 10374 + " external storage"); 10375 } 10376 } 10377 10378 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 10379 throws RemoteException { 10380 long result = 0; 10381 for (File path : paths) { 10382 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 10383 } 10384 return result; 10385 } 10386 10387 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 10388 for (File path : paths) { 10389 try { 10390 mcs.clearDirectory(path.getAbsolutePath()); 10391 } catch (RemoteException e) { 10392 } 10393 } 10394 } 10395 10396 static class OriginInfo { 10397 /** 10398 * Location where install is coming from, before it has been 10399 * copied/renamed into place. This could be a single monolithic APK 10400 * file, or a cluster directory. This location may be untrusted. 10401 */ 10402 final File file; 10403 final String cid; 10404 10405 /** 10406 * Flag indicating that {@link #file} or {@link #cid} has already been 10407 * staged, meaning downstream users don't need to defensively copy the 10408 * contents. 10409 */ 10410 final boolean staged; 10411 10412 /** 10413 * Flag indicating that {@link #file} or {@link #cid} is an already 10414 * installed app that is being moved. 10415 */ 10416 final boolean existing; 10417 10418 final String resolvedPath; 10419 final File resolvedFile; 10420 10421 static OriginInfo fromNothing() { 10422 return new OriginInfo(null, null, false, false); 10423 } 10424 10425 static OriginInfo fromUntrustedFile(File file) { 10426 return new OriginInfo(file, null, false, false); 10427 } 10428 10429 static OriginInfo fromExistingFile(File file) { 10430 return new OriginInfo(file, null, false, true); 10431 } 10432 10433 static OriginInfo fromStagedFile(File file) { 10434 return new OriginInfo(file, null, true, false); 10435 } 10436 10437 static OriginInfo fromStagedContainer(String cid) { 10438 return new OriginInfo(null, cid, true, false); 10439 } 10440 10441 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 10442 this.file = file; 10443 this.cid = cid; 10444 this.staged = staged; 10445 this.existing = existing; 10446 10447 if (cid != null) { 10448 resolvedPath = PackageHelper.getSdDir(cid); 10449 resolvedFile = new File(resolvedPath); 10450 } else if (file != null) { 10451 resolvedPath = file.getAbsolutePath(); 10452 resolvedFile = file; 10453 } else { 10454 resolvedPath = null; 10455 resolvedFile = null; 10456 } 10457 } 10458 } 10459 10460 class MoveInfo { 10461 final int moveId; 10462 final String fromUuid; 10463 final String toUuid; 10464 final String packageName; 10465 final String dataAppName; 10466 final int appId; 10467 final String seinfo; 10468 10469 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 10470 String dataAppName, int appId, String seinfo) { 10471 this.moveId = moveId; 10472 this.fromUuid = fromUuid; 10473 this.toUuid = toUuid; 10474 this.packageName = packageName; 10475 this.dataAppName = dataAppName; 10476 this.appId = appId; 10477 this.seinfo = seinfo; 10478 } 10479 } 10480 10481 class InstallParams extends HandlerParams { 10482 final OriginInfo origin; 10483 final MoveInfo move; 10484 final IPackageInstallObserver2 observer; 10485 int installFlags; 10486 final String installerPackageName; 10487 final String volumeUuid; 10488 final VerificationParams verificationParams; 10489 private InstallArgs mArgs; 10490 private int mRet; 10491 final String packageAbiOverride; 10492 final String[] grantedRuntimePermissions; 10493 10494 10495 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 10496 int installFlags, String installerPackageName, String volumeUuid, 10497 VerificationParams verificationParams, UserHandle user, String packageAbiOverride, 10498 String[] grantedPermissions) { 10499 super(user); 10500 this.origin = origin; 10501 this.move = move; 10502 this.observer = observer; 10503 this.installFlags = installFlags; 10504 this.installerPackageName = installerPackageName; 10505 this.volumeUuid = volumeUuid; 10506 this.verificationParams = verificationParams; 10507 this.packageAbiOverride = packageAbiOverride; 10508 this.grantedRuntimePermissions = grantedPermissions; 10509 } 10510 10511 @Override 10512 public String toString() { 10513 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 10514 + " file=" + origin.file + " cid=" + origin.cid + "}"; 10515 } 10516 10517 public ManifestDigest getManifestDigest() { 10518 if (verificationParams == null) { 10519 return null; 10520 } 10521 return verificationParams.getManifestDigest(); 10522 } 10523 10524 private int installLocationPolicy(PackageInfoLite pkgLite) { 10525 String packageName = pkgLite.packageName; 10526 int installLocation = pkgLite.installLocation; 10527 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10528 // reader 10529 synchronized (mPackages) { 10530 PackageParser.Package pkg = mPackages.get(packageName); 10531 if (pkg != null) { 10532 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 10533 // Check for downgrading. 10534 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 10535 try { 10536 checkDowngrade(pkg, pkgLite); 10537 } catch (PackageManagerException e) { 10538 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 10539 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 10540 } 10541 } 10542 // Check for updated system application. 10543 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10544 if (onSd) { 10545 Slog.w(TAG, "Cannot install update to system app on sdcard"); 10546 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 10547 } 10548 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10549 } else { 10550 if (onSd) { 10551 // Install flag overrides everything. 10552 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10553 } 10554 // If current upgrade specifies particular preference 10555 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 10556 // Application explicitly specified internal. 10557 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10558 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 10559 // App explictly prefers external. Let policy decide 10560 } else { 10561 // Prefer previous location 10562 if (isExternal(pkg)) { 10563 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10564 } 10565 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10566 } 10567 } 10568 } else { 10569 // Invalid install. Return error code 10570 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 10571 } 10572 } 10573 } 10574 // All the special cases have been taken care of. 10575 // Return result based on recommended install location. 10576 if (onSd) { 10577 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10578 } 10579 return pkgLite.recommendedInstallLocation; 10580 } 10581 10582 /* 10583 * Invoke remote method to get package information and install 10584 * location values. Override install location based on default 10585 * policy if needed and then create install arguments based 10586 * on the install location. 10587 */ 10588 public void handleStartCopy() throws RemoteException { 10589 int ret = PackageManager.INSTALL_SUCCEEDED; 10590 10591 // If we're already staged, we've firmly committed to an install location 10592 if (origin.staged) { 10593 if (origin.file != null) { 10594 installFlags |= PackageManager.INSTALL_INTERNAL; 10595 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 10596 } else if (origin.cid != null) { 10597 installFlags |= PackageManager.INSTALL_EXTERNAL; 10598 installFlags &= ~PackageManager.INSTALL_INTERNAL; 10599 } else { 10600 throw new IllegalStateException("Invalid stage location"); 10601 } 10602 } 10603 10604 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10605 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 10606 PackageInfoLite pkgLite = null; 10607 10608 if (onInt && onSd) { 10609 // Check if both bits are set. 10610 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 10611 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 10612 } else { 10613 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 10614 packageAbiOverride); 10615 10616 /* 10617 * If we have too little free space, try to free cache 10618 * before giving up. 10619 */ 10620 if (!origin.staged && pkgLite.recommendedInstallLocation 10621 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 10622 // TODO: focus freeing disk space on the target device 10623 final StorageManager storage = StorageManager.from(mContext); 10624 final long lowThreshold = storage.getStorageLowBytes( 10625 Environment.getDataDirectory()); 10626 10627 final long sizeBytes = mContainerService.calculateInstalledSize( 10628 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 10629 10630 if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) { 10631 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 10632 installFlags, packageAbiOverride); 10633 } 10634 10635 /* 10636 * The cache free must have deleted the file we 10637 * downloaded to install. 10638 * 10639 * TODO: fix the "freeCache" call to not delete 10640 * the file we care about. 10641 */ 10642 if (pkgLite.recommendedInstallLocation 10643 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 10644 pkgLite.recommendedInstallLocation 10645 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 10646 } 10647 } 10648 } 10649 10650 if (ret == PackageManager.INSTALL_SUCCEEDED) { 10651 int loc = pkgLite.recommendedInstallLocation; 10652 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 10653 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 10654 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 10655 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 10656 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 10657 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10658 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 10659 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 10660 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 10661 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 10662 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 10663 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 10664 } else { 10665 // Override with defaults if needed. 10666 loc = installLocationPolicy(pkgLite); 10667 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 10668 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 10669 } else if (!onSd && !onInt) { 10670 // Override install location with flags 10671 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 10672 // Set the flag to install on external media. 10673 installFlags |= PackageManager.INSTALL_EXTERNAL; 10674 installFlags &= ~PackageManager.INSTALL_INTERNAL; 10675 } else { 10676 // Make sure the flag for installing on external 10677 // media is unset 10678 installFlags |= PackageManager.INSTALL_INTERNAL; 10679 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 10680 } 10681 } 10682 } 10683 } 10684 10685 final InstallArgs args = createInstallArgs(this); 10686 mArgs = args; 10687 10688 if (ret == PackageManager.INSTALL_SUCCEEDED) { 10689 /* 10690 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 10691 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 10692 */ 10693 int userIdentifier = getUser().getIdentifier(); 10694 if (userIdentifier == UserHandle.USER_ALL 10695 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) { 10696 userIdentifier = UserHandle.USER_OWNER; 10697 } 10698 10699 /* 10700 * Determine if we have any installed package verifiers. If we 10701 * do, then we'll defer to them to verify the packages. 10702 */ 10703 final int requiredUid = mRequiredVerifierPackage == null ? -1 10704 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 10705 if (!origin.existing && requiredUid != -1 10706 && isVerificationEnabled(userIdentifier, installFlags)) { 10707 final Intent verification = new Intent( 10708 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 10709 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10710 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 10711 PACKAGE_MIME_TYPE); 10712 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10713 10714 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 10715 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 10716 0 /* TODO: Which userId? */); 10717 10718 if (DEBUG_VERIFY) { 10719 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 10720 + verification.toString() + " with " + pkgLite.verifiers.length 10721 + " optional verifiers"); 10722 } 10723 10724 final int verificationId = mPendingVerificationToken++; 10725 10726 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10727 10728 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 10729 installerPackageName); 10730 10731 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 10732 installFlags); 10733 10734 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 10735 pkgLite.packageName); 10736 10737 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 10738 pkgLite.versionCode); 10739 10740 if (verificationParams != null) { 10741 if (verificationParams.getVerificationURI() != null) { 10742 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 10743 verificationParams.getVerificationURI()); 10744 } 10745 if (verificationParams.getOriginatingURI() != null) { 10746 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 10747 verificationParams.getOriginatingURI()); 10748 } 10749 if (verificationParams.getReferrer() != null) { 10750 verification.putExtra(Intent.EXTRA_REFERRER, 10751 verificationParams.getReferrer()); 10752 } 10753 if (verificationParams.getOriginatingUid() >= 0) { 10754 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 10755 verificationParams.getOriginatingUid()); 10756 } 10757 if (verificationParams.getInstallerUid() >= 0) { 10758 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 10759 verificationParams.getInstallerUid()); 10760 } 10761 } 10762 10763 final PackageVerificationState verificationState = new PackageVerificationState( 10764 requiredUid, args); 10765 10766 mPendingVerification.append(verificationId, verificationState); 10767 10768 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 10769 receivers, verificationState); 10770 10771 // Apps installed for "all" users use the device owner to verify the app 10772 UserHandle verifierUser = getUser(); 10773 if (verifierUser == UserHandle.ALL) { 10774 verifierUser = UserHandle.OWNER; 10775 } 10776 10777 /* 10778 * If any sufficient verifiers were listed in the package 10779 * manifest, attempt to ask them. 10780 */ 10781 if (sufficientVerifiers != null) { 10782 final int N = sufficientVerifiers.size(); 10783 if (N == 0) { 10784 Slog.i(TAG, "Additional verifiers required, but none installed."); 10785 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 10786 } else { 10787 for (int i = 0; i < N; i++) { 10788 final ComponentName verifierComponent = sufficientVerifiers.get(i); 10789 10790 final Intent sufficientIntent = new Intent(verification); 10791 sufficientIntent.setComponent(verifierComponent); 10792 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 10793 } 10794 } 10795 } 10796 10797 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 10798 mRequiredVerifierPackage, receivers); 10799 if (ret == PackageManager.INSTALL_SUCCEEDED 10800 && mRequiredVerifierPackage != null) { 10801 Trace.asyncTraceBegin( 10802 TRACE_TAG_PACKAGE_MANAGER, "pendingVerification", verificationId); 10803 /* 10804 * Send the intent to the required verification agent, 10805 * but only start the verification timeout after the 10806 * target BroadcastReceivers have run. 10807 */ 10808 verification.setComponent(requiredVerifierComponent); 10809 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 10810 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10811 new BroadcastReceiver() { 10812 @Override 10813 public void onReceive(Context context, Intent intent) { 10814 final Message msg = mHandler 10815 .obtainMessage(CHECK_PENDING_VERIFICATION); 10816 msg.arg1 = verificationId; 10817 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 10818 } 10819 }, null, 0, null, null); 10820 10821 /* 10822 * We don't want the copy to proceed until verification 10823 * succeeds, so null out this field. 10824 */ 10825 mArgs = null; 10826 } 10827 } else { 10828 /* 10829 * No package verification is enabled, so immediately start 10830 * the remote call to initiate copy using temporary file. 10831 */ 10832 ret = args.copyApk(mContainerService, true); 10833 } 10834 } 10835 10836 mRet = ret; 10837 } 10838 10839 @Override 10840 void handleReturnCode() { 10841 // If mArgs is null, then MCS couldn't be reached. When it 10842 // reconnects, it will try again to install. At that point, this 10843 // will succeed. 10844 if (mArgs != null) { 10845 processPendingInstall(mArgs, mRet); 10846 } 10847 } 10848 10849 @Override 10850 void handleServiceError() { 10851 mArgs = createInstallArgs(this); 10852 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10853 } 10854 10855 public boolean isForwardLocked() { 10856 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 10857 } 10858 } 10859 10860 /** 10861 * Used during creation of InstallArgs 10862 * 10863 * @param installFlags package installation flags 10864 * @return true if should be installed on external storage 10865 */ 10866 private static boolean installOnExternalAsec(int installFlags) { 10867 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 10868 return false; 10869 } 10870 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 10871 return true; 10872 } 10873 return false; 10874 } 10875 10876 /** 10877 * Used during creation of InstallArgs 10878 * 10879 * @param installFlags package installation flags 10880 * @return true if should be installed as forward locked 10881 */ 10882 private static boolean installForwardLocked(int installFlags) { 10883 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 10884 } 10885 10886 private InstallArgs createInstallArgs(InstallParams params) { 10887 if (params.move != null) { 10888 return new MoveInstallArgs(params); 10889 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 10890 return new AsecInstallArgs(params); 10891 } else { 10892 return new FileInstallArgs(params); 10893 } 10894 } 10895 10896 /** 10897 * Create args that describe an existing installed package. Typically used 10898 * when cleaning up old installs, or used as a move source. 10899 */ 10900 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 10901 String resourcePath, String[] instructionSets) { 10902 final boolean isInAsec; 10903 if (installOnExternalAsec(installFlags)) { 10904 /* Apps on SD card are always in ASEC containers. */ 10905 isInAsec = true; 10906 } else if (installForwardLocked(installFlags) 10907 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 10908 /* 10909 * Forward-locked apps are only in ASEC containers if they're the 10910 * new style 10911 */ 10912 isInAsec = true; 10913 } else { 10914 isInAsec = false; 10915 } 10916 10917 if (isInAsec) { 10918 return new AsecInstallArgs(codePath, instructionSets, 10919 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 10920 } else { 10921 return new FileInstallArgs(codePath, resourcePath, instructionSets); 10922 } 10923 } 10924 10925 static abstract class InstallArgs { 10926 /** @see InstallParams#origin */ 10927 final OriginInfo origin; 10928 /** @see InstallParams#move */ 10929 final MoveInfo move; 10930 10931 final IPackageInstallObserver2 observer; 10932 // Always refers to PackageManager flags only 10933 final int installFlags; 10934 final String installerPackageName; 10935 final String volumeUuid; 10936 final ManifestDigest manifestDigest; 10937 final UserHandle user; 10938 final String abiOverride; 10939 final String[] installGrantPermissions; 10940 10941 // The list of instruction sets supported by this app. This is currently 10942 // only used during the rmdex() phase to clean up resources. We can get rid of this 10943 // if we move dex files under the common app path. 10944 /* nullable */ String[] instructionSets; 10945 10946 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 10947 int installFlags, String installerPackageName, String volumeUuid, 10948 ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, 10949 String abiOverride, String[] installGrantPermissions) { 10950 this.origin = origin; 10951 this.move = move; 10952 this.installFlags = installFlags; 10953 this.observer = observer; 10954 this.installerPackageName = installerPackageName; 10955 this.volumeUuid = volumeUuid; 10956 this.manifestDigest = manifestDigest; 10957 this.user = user; 10958 this.instructionSets = instructionSets; 10959 this.abiOverride = abiOverride; 10960 this.installGrantPermissions = installGrantPermissions; 10961 } 10962 10963 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 10964 abstract int doPreInstall(int status); 10965 10966 /** 10967 * Rename package into final resting place. All paths on the given 10968 * scanned package should be updated to reflect the rename. 10969 */ 10970 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 10971 abstract int doPostInstall(int status, int uid); 10972 10973 /** @see PackageSettingBase#codePathString */ 10974 abstract String getCodePath(); 10975 /** @see PackageSettingBase#resourcePathString */ 10976 abstract String getResourcePath(); 10977 10978 // Need installer lock especially for dex file removal. 10979 abstract void cleanUpResourcesLI(); 10980 abstract boolean doPostDeleteLI(boolean delete); 10981 10982 /** 10983 * Called before the source arguments are copied. This is used mostly 10984 * for MoveParams when it needs to read the source file to put it in the 10985 * destination. 10986 */ 10987 int doPreCopy() { 10988 return PackageManager.INSTALL_SUCCEEDED; 10989 } 10990 10991 /** 10992 * Called after the source arguments are copied. This is used mostly for 10993 * MoveParams when it needs to read the source file to put it in the 10994 * destination. 10995 * 10996 * @return 10997 */ 10998 int doPostCopy(int uid) { 10999 return PackageManager.INSTALL_SUCCEEDED; 11000 } 11001 11002 protected boolean isFwdLocked() { 11003 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11004 } 11005 11006 protected boolean isExternalAsec() { 11007 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11008 } 11009 11010 UserHandle getUser() { 11011 return user; 11012 } 11013 } 11014 11015 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 11016 if (!allCodePaths.isEmpty()) { 11017 if (instructionSets == null) { 11018 throw new IllegalStateException("instructionSet == null"); 11019 } 11020 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 11021 for (String codePath : allCodePaths) { 11022 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 11023 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 11024 if (retCode < 0) { 11025 Slog.w(TAG, "Couldn't remove dex file for package: " 11026 + " at location " + codePath + ", retcode=" + retCode); 11027 // we don't consider this to be a failure of the core package deletion 11028 } 11029 } 11030 } 11031 } 11032 } 11033 11034 /** 11035 * Logic to handle installation of non-ASEC applications, including copying 11036 * and renaming logic. 11037 */ 11038 class FileInstallArgs extends InstallArgs { 11039 private File codeFile; 11040 private File resourceFile; 11041 11042 // Example topology: 11043 // /data/app/com.example/base.apk 11044 // /data/app/com.example/split_foo.apk 11045 // /data/app/com.example/lib/arm/libfoo.so 11046 // /data/app/com.example/lib/arm64/libfoo.so 11047 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 11048 11049 /** New install */ 11050 FileInstallArgs(InstallParams params) { 11051 super(params.origin, params.move, params.observer, params.installFlags, 11052 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11053 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11054 params.grantedRuntimePermissions); 11055 if (isFwdLocked()) { 11056 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 11057 } 11058 } 11059 11060 /** Existing install */ 11061 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 11062 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets, 11063 null, null); 11064 this.codeFile = (codePath != null) ? new File(codePath) : null; 11065 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 11066 } 11067 11068 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11069 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 11070 try { 11071 return doCopyApk(imcs, temp); 11072 } finally { 11073 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 11074 } 11075 } 11076 11077 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11078 if (origin.staged) { 11079 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 11080 codeFile = origin.file; 11081 resourceFile = origin.file; 11082 return PackageManager.INSTALL_SUCCEEDED; 11083 } 11084 11085 try { 11086 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid); 11087 codeFile = tempDir; 11088 resourceFile = tempDir; 11089 } catch (IOException e) { 11090 Slog.w(TAG, "Failed to create copy file: " + e); 11091 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11092 } 11093 11094 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 11095 @Override 11096 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 11097 if (!FileUtils.isValidExtFilename(name)) { 11098 throw new IllegalArgumentException("Invalid filename: " + name); 11099 } 11100 try { 11101 final File file = new File(codeFile, name); 11102 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 11103 O_RDWR | O_CREAT, 0644); 11104 Os.chmod(file.getAbsolutePath(), 0644); 11105 return new ParcelFileDescriptor(fd); 11106 } catch (ErrnoException e) { 11107 throw new RemoteException("Failed to open: " + e.getMessage()); 11108 } 11109 } 11110 }; 11111 11112 int ret = PackageManager.INSTALL_SUCCEEDED; 11113 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 11114 if (ret != PackageManager.INSTALL_SUCCEEDED) { 11115 Slog.e(TAG, "Failed to copy package"); 11116 return ret; 11117 } 11118 11119 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 11120 NativeLibraryHelper.Handle handle = null; 11121 try { 11122 handle = NativeLibraryHelper.Handle.create(codeFile); 11123 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 11124 abiOverride); 11125 } catch (IOException e) { 11126 Slog.e(TAG, "Copying native libraries failed", e); 11127 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11128 } finally { 11129 IoUtils.closeQuietly(handle); 11130 } 11131 11132 return ret; 11133 } 11134 11135 int doPreInstall(int status) { 11136 if (status != PackageManager.INSTALL_SUCCEEDED) { 11137 cleanUp(); 11138 } 11139 return status; 11140 } 11141 11142 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11143 if (status != PackageManager.INSTALL_SUCCEEDED) { 11144 cleanUp(); 11145 return false; 11146 } 11147 11148 final File targetDir = codeFile.getParentFile(); 11149 final File beforeCodeFile = codeFile; 11150 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 11151 11152 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 11153 try { 11154 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 11155 } catch (ErrnoException e) { 11156 Slog.w(TAG, "Failed to rename", e); 11157 return false; 11158 } 11159 11160 if (!SELinux.restoreconRecursive(afterCodeFile)) { 11161 Slog.w(TAG, "Failed to restorecon"); 11162 return false; 11163 } 11164 11165 // Reflect the rename internally 11166 codeFile = afterCodeFile; 11167 resourceFile = afterCodeFile; 11168 11169 // Reflect the rename in scanned details 11170 pkg.codePath = afterCodeFile.getAbsolutePath(); 11171 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11172 pkg.baseCodePath); 11173 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11174 pkg.splitCodePaths); 11175 11176 // Reflect the rename in app info 11177 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11178 pkg.applicationInfo.setCodePath(pkg.codePath); 11179 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11180 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11181 pkg.applicationInfo.setResourcePath(pkg.codePath); 11182 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11183 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11184 11185 return true; 11186 } 11187 11188 int doPostInstall(int status, int uid) { 11189 if (status != PackageManager.INSTALL_SUCCEEDED) { 11190 cleanUp(); 11191 } 11192 return status; 11193 } 11194 11195 @Override 11196 String getCodePath() { 11197 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 11198 } 11199 11200 @Override 11201 String getResourcePath() { 11202 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 11203 } 11204 11205 private boolean cleanUp() { 11206 if (codeFile == null || !codeFile.exists()) { 11207 return false; 11208 } 11209 11210 if (codeFile.isDirectory()) { 11211 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 11212 } else { 11213 codeFile.delete(); 11214 } 11215 11216 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 11217 resourceFile.delete(); 11218 } 11219 11220 return true; 11221 } 11222 11223 void cleanUpResourcesLI() { 11224 // Try enumerating all code paths before deleting 11225 List<String> allCodePaths = Collections.EMPTY_LIST; 11226 if (codeFile != null && codeFile.exists()) { 11227 try { 11228 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 11229 allCodePaths = pkg.getAllCodePaths(); 11230 } catch (PackageParserException e) { 11231 // Ignored; we tried our best 11232 } 11233 } 11234 11235 cleanUp(); 11236 removeDexFiles(allCodePaths, instructionSets); 11237 } 11238 11239 boolean doPostDeleteLI(boolean delete) { 11240 // XXX err, shouldn't we respect the delete flag? 11241 cleanUpResourcesLI(); 11242 return true; 11243 } 11244 } 11245 11246 private boolean isAsecExternal(String cid) { 11247 final String asecPath = PackageHelper.getSdFilesystem(cid); 11248 return !asecPath.startsWith(mAsecInternalPath); 11249 } 11250 11251 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 11252 PackageManagerException { 11253 if (copyRet < 0) { 11254 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 11255 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 11256 throw new PackageManagerException(copyRet, message); 11257 } 11258 } 11259 } 11260 11261 /** 11262 * Extract the MountService "container ID" from the full code path of an 11263 * .apk. 11264 */ 11265 static String cidFromCodePath(String fullCodePath) { 11266 int eidx = fullCodePath.lastIndexOf("/"); 11267 String subStr1 = fullCodePath.substring(0, eidx); 11268 int sidx = subStr1.lastIndexOf("/"); 11269 return subStr1.substring(sidx+1, eidx); 11270 } 11271 11272 /** 11273 * Logic to handle installation of ASEC applications, including copying and 11274 * renaming logic. 11275 */ 11276 class AsecInstallArgs extends InstallArgs { 11277 static final String RES_FILE_NAME = "pkg.apk"; 11278 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 11279 11280 String cid; 11281 String packagePath; 11282 String resourcePath; 11283 11284 /** New install */ 11285 AsecInstallArgs(InstallParams params) { 11286 super(params.origin, params.move, params.observer, params.installFlags, 11287 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11288 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11289 params.grantedRuntimePermissions); 11290 } 11291 11292 /** Existing install */ 11293 AsecInstallArgs(String fullCodePath, String[] instructionSets, 11294 boolean isExternal, boolean isForwardLocked) { 11295 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 11296 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 11297 instructionSets, null, null); 11298 // Hackily pretend we're still looking at a full code path 11299 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 11300 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 11301 } 11302 11303 // Extract cid from fullCodePath 11304 int eidx = fullCodePath.lastIndexOf("/"); 11305 String subStr1 = fullCodePath.substring(0, eidx); 11306 int sidx = subStr1.lastIndexOf("/"); 11307 cid = subStr1.substring(sidx+1, eidx); 11308 setMountPath(subStr1); 11309 } 11310 11311 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 11312 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 11313 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 11314 instructionSets, null, null); 11315 this.cid = cid; 11316 setMountPath(PackageHelper.getSdDir(cid)); 11317 } 11318 11319 void createCopyFile() { 11320 cid = mInstallerService.allocateExternalStageCidLegacy(); 11321 } 11322 11323 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11324 if (origin.staged) { 11325 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 11326 cid = origin.cid; 11327 setMountPath(PackageHelper.getSdDir(cid)); 11328 return PackageManager.INSTALL_SUCCEEDED; 11329 } 11330 11331 if (temp) { 11332 createCopyFile(); 11333 } else { 11334 /* 11335 * Pre-emptively destroy the container since it's destroyed if 11336 * copying fails due to it existing anyway. 11337 */ 11338 PackageHelper.destroySdDir(cid); 11339 } 11340 11341 final String newMountPath = imcs.copyPackageToContainer( 11342 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 11343 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 11344 11345 if (newMountPath != null) { 11346 setMountPath(newMountPath); 11347 return PackageManager.INSTALL_SUCCEEDED; 11348 } else { 11349 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11350 } 11351 } 11352 11353 @Override 11354 String getCodePath() { 11355 return packagePath; 11356 } 11357 11358 @Override 11359 String getResourcePath() { 11360 return resourcePath; 11361 } 11362 11363 int doPreInstall(int status) { 11364 if (status != PackageManager.INSTALL_SUCCEEDED) { 11365 // Destroy container 11366 PackageHelper.destroySdDir(cid); 11367 } else { 11368 boolean mounted = PackageHelper.isContainerMounted(cid); 11369 if (!mounted) { 11370 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 11371 Process.SYSTEM_UID); 11372 if (newMountPath != null) { 11373 setMountPath(newMountPath); 11374 } else { 11375 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11376 } 11377 } 11378 } 11379 return status; 11380 } 11381 11382 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11383 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 11384 String newMountPath = null; 11385 if (PackageHelper.isContainerMounted(cid)) { 11386 // Unmount the container 11387 if (!PackageHelper.unMountSdDir(cid)) { 11388 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 11389 return false; 11390 } 11391 } 11392 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 11393 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 11394 " which might be stale. Will try to clean up."); 11395 // Clean up the stale container and proceed to recreate. 11396 if (!PackageHelper.destroySdDir(newCacheId)) { 11397 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 11398 return false; 11399 } 11400 // Successfully cleaned up stale container. Try to rename again. 11401 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 11402 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 11403 + " inspite of cleaning it up."); 11404 return false; 11405 } 11406 } 11407 if (!PackageHelper.isContainerMounted(newCacheId)) { 11408 Slog.w(TAG, "Mounting container " + newCacheId); 11409 newMountPath = PackageHelper.mountSdDir(newCacheId, 11410 getEncryptKey(), Process.SYSTEM_UID); 11411 } else { 11412 newMountPath = PackageHelper.getSdDir(newCacheId); 11413 } 11414 if (newMountPath == null) { 11415 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 11416 return false; 11417 } 11418 Log.i(TAG, "Succesfully renamed " + cid + 11419 " to " + newCacheId + 11420 " at new path: " + newMountPath); 11421 cid = newCacheId; 11422 11423 final File beforeCodeFile = new File(packagePath); 11424 setMountPath(newMountPath); 11425 final File afterCodeFile = new File(packagePath); 11426 11427 // Reflect the rename in scanned details 11428 pkg.codePath = afterCodeFile.getAbsolutePath(); 11429 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11430 pkg.baseCodePath); 11431 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11432 pkg.splitCodePaths); 11433 11434 // Reflect the rename in app info 11435 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11436 pkg.applicationInfo.setCodePath(pkg.codePath); 11437 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11438 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11439 pkg.applicationInfo.setResourcePath(pkg.codePath); 11440 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11441 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11442 11443 return true; 11444 } 11445 11446 private void setMountPath(String mountPath) { 11447 final File mountFile = new File(mountPath); 11448 11449 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 11450 if (monolithicFile.exists()) { 11451 packagePath = monolithicFile.getAbsolutePath(); 11452 if (isFwdLocked()) { 11453 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 11454 } else { 11455 resourcePath = packagePath; 11456 } 11457 } else { 11458 packagePath = mountFile.getAbsolutePath(); 11459 resourcePath = packagePath; 11460 } 11461 } 11462 11463 int doPostInstall(int status, int uid) { 11464 if (status != PackageManager.INSTALL_SUCCEEDED) { 11465 cleanUp(); 11466 } else { 11467 final int groupOwner; 11468 final String protectedFile; 11469 if (isFwdLocked()) { 11470 groupOwner = UserHandle.getSharedAppGid(uid); 11471 protectedFile = RES_FILE_NAME; 11472 } else { 11473 groupOwner = -1; 11474 protectedFile = null; 11475 } 11476 11477 if (uid < Process.FIRST_APPLICATION_UID 11478 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 11479 Slog.e(TAG, "Failed to finalize " + cid); 11480 PackageHelper.destroySdDir(cid); 11481 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11482 } 11483 11484 boolean mounted = PackageHelper.isContainerMounted(cid); 11485 if (!mounted) { 11486 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 11487 } 11488 } 11489 return status; 11490 } 11491 11492 private void cleanUp() { 11493 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 11494 11495 // Destroy secure container 11496 PackageHelper.destroySdDir(cid); 11497 } 11498 11499 private List<String> getAllCodePaths() { 11500 final File codeFile = new File(getCodePath()); 11501 if (codeFile != null && codeFile.exists()) { 11502 try { 11503 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 11504 return pkg.getAllCodePaths(); 11505 } catch (PackageParserException e) { 11506 // Ignored; we tried our best 11507 } 11508 } 11509 return Collections.EMPTY_LIST; 11510 } 11511 11512 void cleanUpResourcesLI() { 11513 // Enumerate all code paths before deleting 11514 cleanUpResourcesLI(getAllCodePaths()); 11515 } 11516 11517 private void cleanUpResourcesLI(List<String> allCodePaths) { 11518 cleanUp(); 11519 removeDexFiles(allCodePaths, instructionSets); 11520 } 11521 11522 String getPackageName() { 11523 return getAsecPackageName(cid); 11524 } 11525 11526 boolean doPostDeleteLI(boolean delete) { 11527 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 11528 final List<String> allCodePaths = getAllCodePaths(); 11529 boolean mounted = PackageHelper.isContainerMounted(cid); 11530 if (mounted) { 11531 // Unmount first 11532 if (PackageHelper.unMountSdDir(cid)) { 11533 mounted = false; 11534 } 11535 } 11536 if (!mounted && delete) { 11537 cleanUpResourcesLI(allCodePaths); 11538 } 11539 return !mounted; 11540 } 11541 11542 @Override 11543 int doPreCopy() { 11544 if (isFwdLocked()) { 11545 if (!PackageHelper.fixSdPermissions(cid, 11546 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 11547 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11548 } 11549 } 11550 11551 return PackageManager.INSTALL_SUCCEEDED; 11552 } 11553 11554 @Override 11555 int doPostCopy(int uid) { 11556 if (isFwdLocked()) { 11557 if (uid < Process.FIRST_APPLICATION_UID 11558 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 11559 RES_FILE_NAME)) { 11560 Slog.e(TAG, "Failed to finalize " + cid); 11561 PackageHelper.destroySdDir(cid); 11562 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11563 } 11564 } 11565 11566 return PackageManager.INSTALL_SUCCEEDED; 11567 } 11568 } 11569 11570 /** 11571 * Logic to handle movement of existing installed applications. 11572 */ 11573 class MoveInstallArgs extends InstallArgs { 11574 private File codeFile; 11575 private File resourceFile; 11576 11577 /** New install */ 11578 MoveInstallArgs(InstallParams params) { 11579 super(params.origin, params.move, params.observer, params.installFlags, 11580 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11581 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11582 params.grantedRuntimePermissions); 11583 } 11584 11585 int copyApk(IMediaContainerService imcs, boolean temp) { 11586 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 11587 + move.fromUuid + " to " + move.toUuid); 11588 synchronized (mInstaller) { 11589 if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName, 11590 move.dataAppName, move.appId, move.seinfo) != 0) { 11591 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11592 } 11593 } 11594 11595 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 11596 resourceFile = codeFile; 11597 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 11598 11599 return PackageManager.INSTALL_SUCCEEDED; 11600 } 11601 11602 int doPreInstall(int status) { 11603 if (status != PackageManager.INSTALL_SUCCEEDED) { 11604 cleanUp(move.toUuid); 11605 } 11606 return status; 11607 } 11608 11609 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11610 if (status != PackageManager.INSTALL_SUCCEEDED) { 11611 cleanUp(move.toUuid); 11612 return false; 11613 } 11614 11615 // Reflect the move in app info 11616 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11617 pkg.applicationInfo.setCodePath(pkg.codePath); 11618 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11619 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11620 pkg.applicationInfo.setResourcePath(pkg.codePath); 11621 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11622 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11623 11624 return true; 11625 } 11626 11627 int doPostInstall(int status, int uid) { 11628 if (status == PackageManager.INSTALL_SUCCEEDED) { 11629 cleanUp(move.fromUuid); 11630 } else { 11631 cleanUp(move.toUuid); 11632 } 11633 return status; 11634 } 11635 11636 @Override 11637 String getCodePath() { 11638 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 11639 } 11640 11641 @Override 11642 String getResourcePath() { 11643 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 11644 } 11645 11646 private boolean cleanUp(String volumeUuid) { 11647 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 11648 move.dataAppName); 11649 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 11650 synchronized (mInstallLock) { 11651 // Clean up both app data and code 11652 removeDataDirsLI(volumeUuid, move.packageName); 11653 if (codeFile.isDirectory()) { 11654 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 11655 } else { 11656 codeFile.delete(); 11657 } 11658 } 11659 return true; 11660 } 11661 11662 void cleanUpResourcesLI() { 11663 throw new UnsupportedOperationException(); 11664 } 11665 11666 boolean doPostDeleteLI(boolean delete) { 11667 throw new UnsupportedOperationException(); 11668 } 11669 } 11670 11671 static String getAsecPackageName(String packageCid) { 11672 int idx = packageCid.lastIndexOf("-"); 11673 if (idx == -1) { 11674 return packageCid; 11675 } 11676 return packageCid.substring(0, idx); 11677 } 11678 11679 // Utility method used to create code paths based on package name and available index. 11680 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 11681 String idxStr = ""; 11682 int idx = 1; 11683 // Fall back to default value of idx=1 if prefix is not 11684 // part of oldCodePath 11685 if (oldCodePath != null) { 11686 String subStr = oldCodePath; 11687 // Drop the suffix right away 11688 if (suffix != null && subStr.endsWith(suffix)) { 11689 subStr = subStr.substring(0, subStr.length() - suffix.length()); 11690 } 11691 // If oldCodePath already contains prefix find out the 11692 // ending index to either increment or decrement. 11693 int sidx = subStr.lastIndexOf(prefix); 11694 if (sidx != -1) { 11695 subStr = subStr.substring(sidx + prefix.length()); 11696 if (subStr != null) { 11697 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 11698 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 11699 } 11700 try { 11701 idx = Integer.parseInt(subStr); 11702 if (idx <= 1) { 11703 idx++; 11704 } else { 11705 idx--; 11706 } 11707 } catch(NumberFormatException e) { 11708 } 11709 } 11710 } 11711 } 11712 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 11713 return prefix + idxStr; 11714 } 11715 11716 private File getNextCodePath(File targetDir, String packageName) { 11717 int suffix = 1; 11718 File result; 11719 do { 11720 result = new File(targetDir, packageName + "-" + suffix); 11721 suffix++; 11722 } while (result.exists()); 11723 return result; 11724 } 11725 11726 // Utility method that returns the relative package path with respect 11727 // to the installation directory. Like say for /data/data/com.test-1.apk 11728 // string com.test-1 is returned. 11729 static String deriveCodePathName(String codePath) { 11730 if (codePath == null) { 11731 return null; 11732 } 11733 final File codeFile = new File(codePath); 11734 final String name = codeFile.getName(); 11735 if (codeFile.isDirectory()) { 11736 return name; 11737 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 11738 final int lastDot = name.lastIndexOf('.'); 11739 return name.substring(0, lastDot); 11740 } else { 11741 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 11742 return null; 11743 } 11744 } 11745 11746 class PackageInstalledInfo { 11747 String name; 11748 int uid; 11749 // The set of users that originally had this package installed. 11750 int[] origUsers; 11751 // The set of users that now have this package installed. 11752 int[] newUsers; 11753 PackageParser.Package pkg; 11754 int returnCode; 11755 String returnMsg; 11756 PackageRemovedInfo removedInfo; 11757 11758 public void setError(int code, String msg) { 11759 returnCode = code; 11760 returnMsg = msg; 11761 Slog.w(TAG, msg); 11762 } 11763 11764 public void setError(String msg, PackageParserException e) { 11765 returnCode = e.error; 11766 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11767 Slog.w(TAG, msg, e); 11768 } 11769 11770 public void setError(String msg, PackageManagerException e) { 11771 returnCode = e.error; 11772 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11773 Slog.w(TAG, msg, e); 11774 } 11775 11776 // In some error cases we want to convey more info back to the observer 11777 String origPackage; 11778 String origPermission; 11779 } 11780 11781 /* 11782 * Install a non-existing package. 11783 */ 11784 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 11785 UserHandle user, String installerPackageName, String volumeUuid, 11786 PackageInstalledInfo res) { 11787 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 11788 11789 // Remember this for later, in case we need to rollback this install 11790 String pkgName = pkg.packageName; 11791 11792 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 11793 final boolean dataDirExists = Environment 11794 .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_OWNER, pkgName).exists(); 11795 11796 synchronized(mPackages) { 11797 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 11798 // A package with the same name is already installed, though 11799 // it has been renamed to an older name. The package we 11800 // are trying to install should be installed as an update to 11801 // the existing one, but that has not been requested, so bail. 11802 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 11803 + " without first uninstalling package running as " 11804 + mSettings.mRenamedPackages.get(pkgName)); 11805 return; 11806 } 11807 if (mPackages.containsKey(pkgName)) { 11808 // Don't allow installation over an existing package with the same name. 11809 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 11810 + " without first uninstalling."); 11811 return; 11812 } 11813 } 11814 11815 try { 11816 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 11817 System.currentTimeMillis(), user); 11818 11819 updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user); 11820 // delete the partially installed application. the data directory will have to be 11821 // restored if it was already existing 11822 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11823 // remove package from internal structures. Note that we want deletePackageX to 11824 // delete the package data and cache directories that it created in 11825 // scanPackageLocked, unless those directories existed before we even tried to 11826 // install. 11827 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 11828 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 11829 res.removedInfo, true); 11830 } 11831 11832 } catch (PackageManagerException e) { 11833 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11834 } 11835 11836 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 11837 } 11838 11839 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 11840 // Can't rotate keys during boot or if sharedUser. 11841 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 11842 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 11843 return false; 11844 } 11845 // app is using upgradeKeySets; make sure all are valid 11846 KeySetManagerService ksms = mSettings.mKeySetManagerService; 11847 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 11848 for (int i = 0; i < upgradeKeySets.length; i++) { 11849 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 11850 Slog.wtf(TAG, "Package " 11851 + (oldPs.name != null ? oldPs.name : "<null>") 11852 + " contains upgrade-key-set reference to unknown key-set: " 11853 + upgradeKeySets[i] 11854 + " reverting to signatures check."); 11855 return false; 11856 } 11857 } 11858 return true; 11859 } 11860 11861 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 11862 // Upgrade keysets are being used. Determine if new package has a superset of the 11863 // required keys. 11864 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 11865 KeySetManagerService ksms = mSettings.mKeySetManagerService; 11866 for (int i = 0; i < upgradeKeySets.length; i++) { 11867 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 11868 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 11869 return true; 11870 } 11871 } 11872 return false; 11873 } 11874 11875 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 11876 UserHandle user, String installerPackageName, String volumeUuid, 11877 PackageInstalledInfo res) { 11878 final PackageParser.Package oldPackage; 11879 final String pkgName = pkg.packageName; 11880 final int[] allUsers; 11881 final boolean[] perUserInstalled; 11882 11883 // First find the old package info and check signatures 11884 synchronized(mPackages) { 11885 oldPackage = mPackages.get(pkgName); 11886 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 11887 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11888 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 11889 if(!checkUpgradeKeySetLP(ps, pkg)) { 11890 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 11891 "New package not signed by keys specified by upgrade-keysets: " 11892 + pkgName); 11893 return; 11894 } 11895 } else { 11896 // default to original signature matching 11897 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 11898 != PackageManager.SIGNATURE_MATCH) { 11899 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 11900 "New package has a different signature: " + pkgName); 11901 return; 11902 } 11903 } 11904 11905 // In case of rollback, remember per-user/profile install state 11906 allUsers = sUserManager.getUserIds(); 11907 perUserInstalled = new boolean[allUsers.length]; 11908 for (int i = 0; i < allUsers.length; i++) { 11909 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 11910 } 11911 } 11912 11913 boolean sysPkg = (isSystemApp(oldPackage)); 11914 if (sysPkg) { 11915 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 11916 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 11917 } else { 11918 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 11919 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 11920 } 11921 } 11922 11923 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 11924 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 11925 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 11926 String volumeUuid, PackageInstalledInfo res) { 11927 String pkgName = deletedPackage.packageName; 11928 boolean deletedPkg = true; 11929 boolean updatedSettings = false; 11930 11931 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 11932 + deletedPackage); 11933 long origUpdateTime; 11934 if (pkg.mExtras != null) { 11935 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 11936 } else { 11937 origUpdateTime = 0; 11938 } 11939 11940 // First delete the existing package while retaining the data directory 11941 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 11942 res.removedInfo, true)) { 11943 // If the existing package wasn't successfully deleted 11944 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 11945 deletedPkg = false; 11946 } else { 11947 // Successfully deleted the old package; proceed with replace. 11948 11949 // If deleted package lived in a container, give users a chance to 11950 // relinquish resources before killing. 11951 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 11952 if (DEBUG_INSTALL) { 11953 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 11954 } 11955 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 11956 final ArrayList<String> pkgList = new ArrayList<String>(1); 11957 pkgList.add(deletedPackage.applicationInfo.packageName); 11958 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 11959 } 11960 11961 deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName); 11962 try { 11963 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 11964 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 11965 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 11966 perUserInstalled, res, user); 11967 updatedSettings = true; 11968 } catch (PackageManagerException e) { 11969 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11970 } 11971 } 11972 11973 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11974 // remove package from internal structures. Note that we want deletePackageX to 11975 // delete the package data and cache directories that it created in 11976 // scanPackageLocked, unless those directories existed before we even tried to 11977 // install. 11978 if(updatedSettings) { 11979 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 11980 deletePackageLI( 11981 pkgName, null, true, allUsers, perUserInstalled, 11982 PackageManager.DELETE_KEEP_DATA, 11983 res.removedInfo, true); 11984 } 11985 // Since we failed to install the new package we need to restore the old 11986 // package that we deleted. 11987 if (deletedPkg) { 11988 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 11989 File restoreFile = new File(deletedPackage.codePath); 11990 // Parse old package 11991 boolean oldExternal = isExternal(deletedPackage); 11992 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 11993 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 11994 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 11995 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 11996 try { 11997 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null); 11998 } catch (PackageManagerException e) { 11999 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 12000 + e.getMessage()); 12001 return; 12002 } 12003 // Restore of old package succeeded. Update permissions. 12004 // writer 12005 synchronized (mPackages) { 12006 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 12007 UPDATE_PERMISSIONS_ALL); 12008 // can downgrade to reader 12009 mSettings.writeLPr(); 12010 } 12011 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 12012 } 12013 } 12014 } 12015 12016 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 12017 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 12018 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 12019 String volumeUuid, PackageInstalledInfo res) { 12020 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 12021 + ", old=" + deletedPackage); 12022 boolean disabledSystem = false; 12023 boolean updatedSettings = false; 12024 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 12025 if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 12026 != 0) { 12027 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 12028 } 12029 String packageName = deletedPackage.packageName; 12030 if (packageName == null) { 12031 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 12032 "Attempt to delete null packageName."); 12033 return; 12034 } 12035 PackageParser.Package oldPkg; 12036 PackageSetting oldPkgSetting; 12037 // reader 12038 synchronized (mPackages) { 12039 oldPkg = mPackages.get(packageName); 12040 oldPkgSetting = mSettings.mPackages.get(packageName); 12041 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 12042 (oldPkgSetting == null)) { 12043 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 12044 "Couldn't find package:" + packageName + " information"); 12045 return; 12046 } 12047 } 12048 12049 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 12050 12051 res.removedInfo.uid = oldPkg.applicationInfo.uid; 12052 res.removedInfo.removedPackage = packageName; 12053 // Remove existing system package 12054 removePackageLI(oldPkgSetting, true); 12055 // writer 12056 synchronized (mPackages) { 12057 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 12058 if (!disabledSystem && deletedPackage != null) { 12059 // We didn't need to disable the .apk as a current system package, 12060 // which means we are replacing another update that is already 12061 // installed. We need to make sure to delete the older one's .apk. 12062 res.removedInfo.args = createInstallArgsForExisting(0, 12063 deletedPackage.applicationInfo.getCodePath(), 12064 deletedPackage.applicationInfo.getResourcePath(), 12065 getAppDexInstructionSets(deletedPackage.applicationInfo)); 12066 } else { 12067 res.removedInfo.args = null; 12068 } 12069 } 12070 12071 // Successfully disabled the old package. Now proceed with re-installation 12072 deleteCodeCacheDirsLI(pkg.volumeUuid, packageName); 12073 12074 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12075 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 12076 12077 PackageParser.Package newPackage = null; 12078 try { 12079 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 12080 if (newPackage.mExtras != null) { 12081 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 12082 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 12083 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 12084 12085 // is the update attempting to change shared user? that isn't going to work... 12086 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 12087 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 12088 "Forbidding shared user change from " + oldPkgSetting.sharedUser 12089 + " to " + newPkgSetting.sharedUser); 12090 updatedSettings = true; 12091 } 12092 } 12093 12094 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12095 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 12096 perUserInstalled, res, user); 12097 updatedSettings = true; 12098 } 12099 12100 } catch (PackageManagerException e) { 12101 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12102 } 12103 12104 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12105 // Re installation failed. Restore old information 12106 // Remove new pkg information 12107 if (newPackage != null) { 12108 removeInstalledPackageLI(newPackage, true); 12109 } 12110 // Add back the old system package 12111 try { 12112 scanPackageTracedLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 12113 } catch (PackageManagerException e) { 12114 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 12115 } 12116 // Restore the old system information in Settings 12117 synchronized (mPackages) { 12118 if (disabledSystem) { 12119 mSettings.enableSystemPackageLPw(packageName); 12120 } 12121 if (updatedSettings) { 12122 mSettings.setInstallerPackageName(packageName, 12123 oldPkgSetting.installerPackageName); 12124 } 12125 mSettings.writeLPr(); 12126 } 12127 } 12128 } 12129 12130 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 12131 String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, 12132 UserHandle user) { 12133 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 12134 12135 String pkgName = newPackage.packageName; 12136 synchronized (mPackages) { 12137 //write settings. the installStatus will be incomplete at this stage. 12138 //note that the new package setting would have already been 12139 //added to mPackages. It hasn't been persisted yet. 12140 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 12141 mSettings.writeLPr(); 12142 } 12143 12144 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 12145 synchronized (mPackages) { 12146 updatePermissionsLPw(newPackage.packageName, newPackage, 12147 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 12148 ? UPDATE_PERMISSIONS_ALL : 0)); 12149 // For system-bundled packages, we assume that installing an upgraded version 12150 // of the package implies that the user actually wants to run that new code, 12151 // so we enable the package. 12152 PackageSetting ps = mSettings.mPackages.get(pkgName); 12153 if (ps != null) { 12154 if (isSystemApp(newPackage)) { 12155 // NB: implicit assumption that system package upgrades apply to all users 12156 if (DEBUG_INSTALL) { 12157 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 12158 } 12159 if (res.origUsers != null) { 12160 for (int userHandle : res.origUsers) { 12161 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 12162 userHandle, installerPackageName); 12163 } 12164 } 12165 // Also convey the prior install/uninstall state 12166 if (allUsers != null && perUserInstalled != null) { 12167 for (int i = 0; i < allUsers.length; i++) { 12168 if (DEBUG_INSTALL) { 12169 Slog.d(TAG, " user " + allUsers[i] 12170 + " => " + perUserInstalled[i]); 12171 } 12172 ps.setInstalled(perUserInstalled[i], allUsers[i]); 12173 } 12174 // these install state changes will be persisted in the 12175 // upcoming call to mSettings.writeLPr(). 12176 } 12177 } 12178 // It's implied that when a user requests installation, they want the app to be 12179 // installed and enabled. 12180 int userId = user.getIdentifier(); 12181 if (userId != UserHandle.USER_ALL) { 12182 ps.setInstalled(true, userId); 12183 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 12184 } 12185 } 12186 res.name = pkgName; 12187 res.uid = newPackage.applicationInfo.uid; 12188 res.pkg = newPackage; 12189 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 12190 mSettings.setInstallerPackageName(pkgName, installerPackageName); 12191 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12192 //to update install status 12193 mSettings.writeLPr(); 12194 } 12195 12196 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12197 } 12198 12199 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 12200 try { 12201 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 12202 installPackageLI(args, res); 12203 } finally { 12204 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12205 } 12206 } 12207 12208 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 12209 final int installFlags = args.installFlags; 12210 final String installerPackageName = args.installerPackageName; 12211 final String volumeUuid = args.volumeUuid; 12212 final File tmpPackageFile = new File(args.getCodePath()); 12213 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 12214 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 12215 || (args.volumeUuid != null)); 12216 boolean replace = false; 12217 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 12218 if (args.move != null) { 12219 // moving a complete application; perfom an initial scan on the new install location 12220 scanFlags |= SCAN_INITIAL; 12221 } 12222 // Result object to be returned 12223 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12224 12225 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 12226 12227 // Retrieve PackageSettings and parse package 12228 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 12229 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 12230 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 12231 PackageParser pp = new PackageParser(); 12232 pp.setSeparateProcesses(mSeparateProcesses); 12233 pp.setDisplayMetrics(mMetrics); 12234 12235 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 12236 final PackageParser.Package pkg; 12237 try { 12238 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 12239 } catch (PackageParserException e) { 12240 res.setError("Failed parse during installPackageLI", e); 12241 return; 12242 } finally { 12243 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12244 } 12245 12246 // Mark that we have an install time CPU ABI override. 12247 pkg.cpuAbiOverride = args.abiOverride; 12248 12249 String pkgName = res.name = pkg.packageName; 12250 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 12251 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 12252 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 12253 return; 12254 } 12255 } 12256 12257 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 12258 try { 12259 pp.collectCertificates(pkg, parseFlags); 12260 pp.collectManifestDigest(pkg); 12261 } catch (PackageParserException e) { 12262 res.setError("Failed collect during installPackageLI", e); 12263 return; 12264 } finally { 12265 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12266 } 12267 12268 /* If the installer passed in a manifest digest, compare it now. */ 12269 if (args.manifestDigest != null) { 12270 if (DEBUG_INSTALL) { 12271 final String parsedManifest = pkg.manifestDigest == null ? "null" 12272 : pkg.manifestDigest.toString(); 12273 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 12274 + parsedManifest); 12275 } 12276 12277 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 12278 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 12279 return; 12280 } 12281 } else if (DEBUG_INSTALL) { 12282 final String parsedManifest = pkg.manifestDigest == null 12283 ? "null" : pkg.manifestDigest.toString(); 12284 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 12285 } 12286 12287 // Get rid of all references to package scan path via parser. 12288 pp = null; 12289 String oldCodePath = null; 12290 boolean systemApp = false; 12291 synchronized (mPackages) { 12292 // Check if installing already existing package 12293 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12294 String oldName = mSettings.mRenamedPackages.get(pkgName); 12295 if (pkg.mOriginalPackages != null 12296 && pkg.mOriginalPackages.contains(oldName) 12297 && mPackages.containsKey(oldName)) { 12298 // This package is derived from an original package, 12299 // and this device has been updating from that original 12300 // name. We must continue using the original name, so 12301 // rename the new package here. 12302 pkg.setPackageName(oldName); 12303 pkgName = pkg.packageName; 12304 replace = true; 12305 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 12306 + oldName + " pkgName=" + pkgName); 12307 } else if (mPackages.containsKey(pkgName)) { 12308 // This package, under its official name, already exists 12309 // on the device; we should replace it. 12310 replace = true; 12311 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 12312 } 12313 12314 // Prevent apps opting out from runtime permissions 12315 if (replace) { 12316 PackageParser.Package oldPackage = mPackages.get(pkgName); 12317 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 12318 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 12319 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 12320 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 12321 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 12322 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 12323 + " doesn't support runtime permissions but the old" 12324 + " target SDK " + oldTargetSdk + " does."); 12325 return; 12326 } 12327 } 12328 } 12329 12330 PackageSetting ps = mSettings.mPackages.get(pkgName); 12331 if (ps != null) { 12332 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 12333 12334 // Quick sanity check that we're signed correctly if updating; 12335 // we'll check this again later when scanning, but we want to 12336 // bail early here before tripping over redefined permissions. 12337 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 12338 if (!checkUpgradeKeySetLP(ps, pkg)) { 12339 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 12340 + pkg.packageName + " upgrade keys do not match the " 12341 + "previously installed version"); 12342 return; 12343 } 12344 } else { 12345 try { 12346 verifySignaturesLP(ps, pkg); 12347 } catch (PackageManagerException e) { 12348 res.setError(e.error, e.getMessage()); 12349 return; 12350 } 12351 } 12352 12353 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 12354 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 12355 systemApp = (ps.pkg.applicationInfo.flags & 12356 ApplicationInfo.FLAG_SYSTEM) != 0; 12357 } 12358 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 12359 } 12360 12361 // Check whether the newly-scanned package wants to define an already-defined perm 12362 int N = pkg.permissions.size(); 12363 for (int i = N-1; i >= 0; i--) { 12364 PackageParser.Permission perm = pkg.permissions.get(i); 12365 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 12366 if (bp != null) { 12367 // If the defining package is signed with our cert, it's okay. This 12368 // also includes the "updating the same package" case, of course. 12369 // "updating same package" could also involve key-rotation. 12370 final boolean sigsOk; 12371 if (bp.sourcePackage.equals(pkg.packageName) 12372 && (bp.packageSetting instanceof PackageSetting) 12373 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 12374 scanFlags))) { 12375 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 12376 } else { 12377 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 12378 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 12379 } 12380 if (!sigsOk) { 12381 // If the owning package is the system itself, we log but allow 12382 // install to proceed; we fail the install on all other permission 12383 // redefinitions. 12384 if (!bp.sourcePackage.equals("android")) { 12385 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 12386 + pkg.packageName + " attempting to redeclare permission " 12387 + perm.info.name + " already owned by " + bp.sourcePackage); 12388 res.origPermission = perm.info.name; 12389 res.origPackage = bp.sourcePackage; 12390 return; 12391 } else { 12392 Slog.w(TAG, "Package " + pkg.packageName 12393 + " attempting to redeclare system permission " 12394 + perm.info.name + "; ignoring new declaration"); 12395 pkg.permissions.remove(i); 12396 } 12397 } 12398 } 12399 } 12400 12401 } 12402 12403 if (systemApp && onExternal) { 12404 // Disable updates to system apps on sdcard 12405 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 12406 "Cannot install updates to system apps on sdcard"); 12407 return; 12408 } 12409 12410 if (args.move != null) { 12411 // We did an in-place move, so dex is ready to roll 12412 scanFlags |= SCAN_NO_DEX; 12413 scanFlags |= SCAN_MOVE; 12414 12415 synchronized (mPackages) { 12416 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12417 if (ps == null) { 12418 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 12419 "Missing settings for moved package " + pkgName); 12420 } 12421 12422 // We moved the entire application as-is, so bring over the 12423 // previously derived ABI information. 12424 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 12425 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 12426 } 12427 12428 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 12429 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 12430 scanFlags |= SCAN_NO_DEX; 12431 12432 try { 12433 derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride, 12434 true /* extract libs */); 12435 } catch (PackageManagerException pme) { 12436 Slog.e(TAG, "Error deriving application ABI", pme); 12437 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 12438 return; 12439 } 12440 12441 // Run dexopt before old package gets removed, to minimize time when app is unavailable 12442 int result = mPackageDexOptimizer 12443 .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */, 12444 false /* defer */, false /* inclDependencies */); 12445 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 12446 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); 12447 return; 12448 } 12449 } 12450 12451 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 12452 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 12453 return; 12454 } 12455 12456 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 12457 12458 if (replace) { 12459 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 12460 installerPackageName, volumeUuid, res); 12461 } else { 12462 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 12463 args.user, installerPackageName, volumeUuid, res); 12464 } 12465 synchronized (mPackages) { 12466 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12467 if (ps != null) { 12468 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 12469 } 12470 } 12471 } 12472 12473 private void startIntentFilterVerifications(int userId, boolean replacing, 12474 PackageParser.Package pkg) { 12475 if (mIntentFilterVerifierComponent == null) { 12476 Slog.w(TAG, "No IntentFilter verification will not be done as " 12477 + "there is no IntentFilterVerifier available!"); 12478 return; 12479 } 12480 12481 final int verifierUid = getPackageUid( 12482 mIntentFilterVerifierComponent.getPackageName(), 12483 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId); 12484 12485 mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); 12486 final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 12487 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 12488 mHandler.sendMessage(msg); 12489 } 12490 12491 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 12492 PackageParser.Package pkg) { 12493 int size = pkg.activities.size(); 12494 if (size == 0) { 12495 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12496 "No activity, so no need to verify any IntentFilter!"); 12497 return; 12498 } 12499 12500 final boolean hasDomainURLs = hasDomainURLs(pkg); 12501 if (!hasDomainURLs) { 12502 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12503 "No domain URLs, so no need to verify any IntentFilter!"); 12504 return; 12505 } 12506 12507 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 12508 + " if any IntentFilter from the " + size 12509 + " Activities needs verification ..."); 12510 12511 int count = 0; 12512 final String packageName = pkg.packageName; 12513 12514 synchronized (mPackages) { 12515 // If this is a new install and we see that we've already run verification for this 12516 // package, we have nothing to do: it means the state was restored from backup. 12517 if (!replacing) { 12518 IntentFilterVerificationInfo ivi = 12519 mSettings.getIntentFilterVerificationLPr(packageName); 12520 if (ivi != null) { 12521 if (DEBUG_DOMAIN_VERIFICATION) { 12522 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 12523 + ivi.getStatusString()); 12524 } 12525 return; 12526 } 12527 } 12528 12529 // If any filters need to be verified, then all need to be. 12530 boolean needToVerify = false; 12531 for (PackageParser.Activity a : pkg.activities) { 12532 for (ActivityIntentInfo filter : a.intents) { 12533 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 12534 if (DEBUG_DOMAIN_VERIFICATION) { 12535 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 12536 } 12537 needToVerify = true; 12538 break; 12539 } 12540 } 12541 } 12542 12543 if (needToVerify) { 12544 final int verificationId = mIntentFilterVerificationToken++; 12545 for (PackageParser.Activity a : pkg.activities) { 12546 for (ActivityIntentInfo filter : a.intents) { 12547 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 12548 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12549 "Verification needed for IntentFilter:" + filter.toString()); 12550 mIntentFilterVerifier.addOneIntentFilterVerification( 12551 verifierUid, userId, verificationId, filter, packageName); 12552 count++; 12553 } 12554 } 12555 } 12556 } 12557 } 12558 12559 if (count > 0) { 12560 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 12561 + " IntentFilter verification" + (count > 1 ? "s" : "") 12562 + " for userId:" + userId); 12563 mIntentFilterVerifier.startVerifications(userId); 12564 } else { 12565 if (DEBUG_DOMAIN_VERIFICATION) { 12566 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 12567 } 12568 } 12569 } 12570 12571 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 12572 final ComponentName cn = filter.activity.getComponentName(); 12573 final String packageName = cn.getPackageName(); 12574 12575 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 12576 packageName); 12577 if (ivi == null) { 12578 return true; 12579 } 12580 int status = ivi.getStatus(); 12581 switch (status) { 12582 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 12583 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 12584 return true; 12585 12586 default: 12587 // Nothing to do 12588 return false; 12589 } 12590 } 12591 12592 private static boolean isMultiArch(PackageSetting ps) { 12593 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 12594 } 12595 12596 private static boolean isMultiArch(ApplicationInfo info) { 12597 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 12598 } 12599 12600 private static boolean isExternal(PackageParser.Package pkg) { 12601 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12602 } 12603 12604 private static boolean isExternal(PackageSetting ps) { 12605 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12606 } 12607 12608 private static boolean isExternal(ApplicationInfo info) { 12609 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12610 } 12611 12612 private static boolean isSystemApp(PackageParser.Package pkg) { 12613 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12614 } 12615 12616 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 12617 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 12618 } 12619 12620 private static boolean hasDomainURLs(PackageParser.Package pkg) { 12621 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 12622 } 12623 12624 private static boolean isSystemApp(PackageSetting ps) { 12625 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 12626 } 12627 12628 private static boolean isUpdatedSystemApp(PackageSetting ps) { 12629 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 12630 } 12631 12632 private int packageFlagsToInstallFlags(PackageSetting ps) { 12633 int installFlags = 0; 12634 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 12635 // This existing package was an external ASEC install when we have 12636 // the external flag without a UUID 12637 installFlags |= PackageManager.INSTALL_EXTERNAL; 12638 } 12639 if (ps.isForwardLocked()) { 12640 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 12641 } 12642 return installFlags; 12643 } 12644 12645 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 12646 if (isExternal(pkg)) { 12647 if (TextUtils.isEmpty(pkg.volumeUuid)) { 12648 return mSettings.getExternalVersion(); 12649 } else { 12650 return mSettings.findOrCreateVersion(pkg.volumeUuid); 12651 } 12652 } else { 12653 return mSettings.getInternalVersion(); 12654 } 12655 } 12656 12657 private void deleteTempPackageFiles() { 12658 final FilenameFilter filter = new FilenameFilter() { 12659 public boolean accept(File dir, String name) { 12660 return name.startsWith("vmdl") && name.endsWith(".tmp"); 12661 } 12662 }; 12663 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 12664 file.delete(); 12665 } 12666 } 12667 12668 @Override 12669 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 12670 int flags) { 12671 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 12672 flags); 12673 } 12674 12675 @Override 12676 public void deletePackage(final String packageName, 12677 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 12678 mContext.enforceCallingOrSelfPermission( 12679 android.Manifest.permission.DELETE_PACKAGES, null); 12680 Preconditions.checkNotNull(packageName); 12681 Preconditions.checkNotNull(observer); 12682 final int uid = Binder.getCallingUid(); 12683 if (UserHandle.getUserId(uid) != userId) { 12684 mContext.enforceCallingPermission( 12685 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12686 "deletePackage for user " + userId); 12687 } 12688 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 12689 try { 12690 observer.onPackageDeleted(packageName, 12691 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 12692 } catch (RemoteException re) { 12693 } 12694 return; 12695 } 12696 12697 boolean uninstallBlocked = false; 12698 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 12699 int[] users = sUserManager.getUserIds(); 12700 for (int i = 0; i < users.length; ++i) { 12701 if (getBlockUninstallForUser(packageName, users[i])) { 12702 uninstallBlocked = true; 12703 break; 12704 } 12705 } 12706 } else { 12707 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 12708 } 12709 if (uninstallBlocked) { 12710 try { 12711 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 12712 null); 12713 } catch (RemoteException re) { 12714 } 12715 return; 12716 } 12717 12718 if (DEBUG_REMOVE) { 12719 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 12720 } 12721 // Queue up an async operation since the package deletion may take a little while. 12722 mHandler.post(new Runnable() { 12723 public void run() { 12724 mHandler.removeCallbacks(this); 12725 final int returnCode = deletePackageX(packageName, userId, flags); 12726 if (observer != null) { 12727 try { 12728 observer.onPackageDeleted(packageName, returnCode, null); 12729 } catch (RemoteException e) { 12730 Log.i(TAG, "Observer no longer exists."); 12731 } //end catch 12732 } //end if 12733 } //end run 12734 }); 12735 } 12736 12737 private boolean isPackageDeviceAdmin(String packageName, int userId) { 12738 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 12739 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 12740 try { 12741 if (dpm != null) { 12742 if (dpm.isDeviceOwner(packageName)) { 12743 return true; 12744 } 12745 int[] users; 12746 if (userId == UserHandle.USER_ALL) { 12747 users = sUserManager.getUserIds(); 12748 } else { 12749 users = new int[]{userId}; 12750 } 12751 for (int i = 0; i < users.length; ++i) { 12752 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 12753 return true; 12754 } 12755 } 12756 } 12757 } catch (RemoteException e) { 12758 } 12759 return false; 12760 } 12761 12762 /** 12763 * This method is an internal method that could be get invoked either 12764 * to delete an installed package or to clean up a failed installation. 12765 * After deleting an installed package, a broadcast is sent to notify any 12766 * listeners that the package has been installed. For cleaning up a failed 12767 * installation, the broadcast is not necessary since the package's 12768 * installation wouldn't have sent the initial broadcast either 12769 * The key steps in deleting a package are 12770 * deleting the package information in internal structures like mPackages, 12771 * deleting the packages base directories through installd 12772 * updating mSettings to reflect current status 12773 * persisting settings for later use 12774 * sending a broadcast if necessary 12775 */ 12776 private int deletePackageX(String packageName, int userId, int flags) { 12777 final PackageRemovedInfo info = new PackageRemovedInfo(); 12778 final boolean res; 12779 12780 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 12781 ? UserHandle.ALL : new UserHandle(userId); 12782 12783 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 12784 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 12785 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 12786 } 12787 12788 boolean removedForAllUsers = false; 12789 boolean systemUpdate = false; 12790 12791 // for the uninstall-updates case and restricted profiles, remember the per- 12792 // userhandle installed state 12793 int[] allUsers; 12794 boolean[] perUserInstalled; 12795 synchronized (mPackages) { 12796 PackageSetting ps = mSettings.mPackages.get(packageName); 12797 allUsers = sUserManager.getUserIds(); 12798 perUserInstalled = new boolean[allUsers.length]; 12799 for (int i = 0; i < allUsers.length; i++) { 12800 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 12801 } 12802 } 12803 12804 synchronized (mInstallLock) { 12805 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 12806 res = deletePackageLI(packageName, removeForUser, 12807 true, allUsers, perUserInstalled, 12808 flags | REMOVE_CHATTY, info, true); 12809 systemUpdate = info.isRemovedPackageSystemUpdate; 12810 if (res && !systemUpdate && mPackages.get(packageName) == null) { 12811 removedForAllUsers = true; 12812 } 12813 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 12814 + " removedForAllUsers=" + removedForAllUsers); 12815 } 12816 12817 if (res) { 12818 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 12819 12820 // If the removed package was a system update, the old system package 12821 // was re-enabled; we need to broadcast this information 12822 if (systemUpdate) { 12823 Bundle extras = new Bundle(1); 12824 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 12825 ? info.removedAppId : info.uid); 12826 extras.putBoolean(Intent.EXTRA_REPLACING, true); 12827 12828 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 12829 extras, null, null, null); 12830 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 12831 extras, null, null, null); 12832 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 12833 null, packageName, null, null); 12834 } 12835 } 12836 // Force a gc here. 12837 Runtime.getRuntime().gc(); 12838 // Delete the resources here after sending the broadcast to let 12839 // other processes clean up before deleting resources. 12840 if (info.args != null) { 12841 synchronized (mInstallLock) { 12842 info.args.doPostDeleteLI(true); 12843 } 12844 } 12845 12846 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 12847 } 12848 12849 class PackageRemovedInfo { 12850 String removedPackage; 12851 int uid = -1; 12852 int removedAppId = -1; 12853 int[] removedUsers = null; 12854 boolean isRemovedPackageSystemUpdate = false; 12855 // Clean up resources deleted packages. 12856 InstallArgs args = null; 12857 12858 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 12859 Bundle extras = new Bundle(1); 12860 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 12861 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 12862 if (replacing) { 12863 extras.putBoolean(Intent.EXTRA_REPLACING, true); 12864 } 12865 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 12866 if (removedPackage != null) { 12867 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 12868 extras, null, null, removedUsers); 12869 if (fullRemove && !replacing) { 12870 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 12871 extras, null, null, removedUsers); 12872 } 12873 } 12874 if (removedAppId >= 0) { 12875 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 12876 removedUsers); 12877 } 12878 } 12879 } 12880 12881 /* 12882 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 12883 * flag is not set, the data directory is removed as well. 12884 * make sure this flag is set for partially installed apps. If not its meaningless to 12885 * delete a partially installed application. 12886 */ 12887 private void removePackageDataLI(PackageSetting ps, 12888 int[] allUserHandles, boolean[] perUserInstalled, 12889 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 12890 String packageName = ps.name; 12891 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 12892 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 12893 // Retrieve object to delete permissions for shared user later on 12894 final PackageSetting deletedPs; 12895 // reader 12896 synchronized (mPackages) { 12897 deletedPs = mSettings.mPackages.get(packageName); 12898 if (outInfo != null) { 12899 outInfo.removedPackage = packageName; 12900 outInfo.removedUsers = deletedPs != null 12901 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 12902 : null; 12903 } 12904 } 12905 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 12906 removeDataDirsLI(ps.volumeUuid, packageName); 12907 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 12908 } 12909 // writer 12910 synchronized (mPackages) { 12911 if (deletedPs != null) { 12912 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 12913 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 12914 clearDefaultBrowserIfNeeded(packageName); 12915 if (outInfo != null) { 12916 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 12917 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 12918 } 12919 updatePermissionsLPw(deletedPs.name, null, 0); 12920 if (deletedPs.sharedUser != null) { 12921 // Remove permissions associated with package. Since runtime 12922 // permissions are per user we have to kill the removed package 12923 // or packages running under the shared user of the removed 12924 // package if revoking the permissions requested only by the removed 12925 // package is successful and this causes a change in gids. 12926 for (int userId : UserManagerService.getInstance().getUserIds()) { 12927 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 12928 userId); 12929 if (userIdToKill == UserHandle.USER_ALL 12930 || userIdToKill >= UserHandle.USER_OWNER) { 12931 // If gids changed for this user, kill all affected packages. 12932 mHandler.post(new Runnable() { 12933 @Override 12934 public void run() { 12935 // This has to happen with no lock held. 12936 killSettingPackagesForUser(deletedPs, userIdToKill, 12937 KILL_APP_REASON_GIDS_CHANGED); 12938 } 12939 }); 12940 break; 12941 } 12942 } 12943 } 12944 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 12945 } 12946 // make sure to preserve per-user disabled state if this removal was just 12947 // a downgrade of a system app to the factory package 12948 if (allUserHandles != null && perUserInstalled != null) { 12949 if (DEBUG_REMOVE) { 12950 Slog.d(TAG, "Propagating install state across downgrade"); 12951 } 12952 for (int i = 0; i < allUserHandles.length; i++) { 12953 if (DEBUG_REMOVE) { 12954 Slog.d(TAG, " user " + allUserHandles[i] 12955 + " => " + perUserInstalled[i]); 12956 } 12957 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 12958 } 12959 } 12960 } 12961 // can downgrade to reader 12962 if (writeSettings) { 12963 // Save settings now 12964 mSettings.writeLPr(); 12965 } 12966 } 12967 if (outInfo != null) { 12968 // A user ID was deleted here. Go through all users and remove it 12969 // from KeyStore. 12970 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 12971 } 12972 } 12973 12974 static boolean locationIsPrivileged(File path) { 12975 try { 12976 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 12977 .getCanonicalPath(); 12978 return path.getCanonicalPath().startsWith(privilegedAppDir); 12979 } catch (IOException e) { 12980 Slog.e(TAG, "Unable to access code path " + path); 12981 } 12982 return false; 12983 } 12984 12985 /* 12986 * Tries to delete system package. 12987 */ 12988 private boolean deleteSystemPackageLI(PackageSetting newPs, 12989 int[] allUserHandles, boolean[] perUserInstalled, 12990 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 12991 final boolean applyUserRestrictions 12992 = (allUserHandles != null) && (perUserInstalled != null); 12993 PackageSetting disabledPs = null; 12994 // Confirm if the system package has been updated 12995 // An updated system app can be deleted. This will also have to restore 12996 // the system pkg from system partition 12997 // reader 12998 synchronized (mPackages) { 12999 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 13000 } 13001 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 13002 + " disabledPs=" + disabledPs); 13003 if (disabledPs == null) { 13004 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 13005 return false; 13006 } else if (DEBUG_REMOVE) { 13007 Slog.d(TAG, "Deleting system pkg from data partition"); 13008 } 13009 if (DEBUG_REMOVE) { 13010 if (applyUserRestrictions) { 13011 Slog.d(TAG, "Remembering install states:"); 13012 for (int i = 0; i < allUserHandles.length; i++) { 13013 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 13014 } 13015 } 13016 } 13017 // Delete the updated package 13018 outInfo.isRemovedPackageSystemUpdate = true; 13019 if (disabledPs.versionCode < newPs.versionCode) { 13020 // Delete data for downgrades 13021 flags &= ~PackageManager.DELETE_KEEP_DATA; 13022 } else { 13023 // Preserve data by setting flag 13024 flags |= PackageManager.DELETE_KEEP_DATA; 13025 } 13026 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 13027 allUserHandles, perUserInstalled, outInfo, writeSettings); 13028 if (!ret) { 13029 return false; 13030 } 13031 // writer 13032 synchronized (mPackages) { 13033 // Reinstate the old system package 13034 mSettings.enableSystemPackageLPw(newPs.name); 13035 // Remove any native libraries from the upgraded package. 13036 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 13037 } 13038 // Install the system package 13039 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 13040 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 13041 if (locationIsPrivileged(disabledPs.codePath)) { 13042 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13043 } 13044 13045 final PackageParser.Package newPkg; 13046 try { 13047 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 13048 } catch (PackageManagerException e) { 13049 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 13050 return false; 13051 } 13052 13053 // writer 13054 synchronized (mPackages) { 13055 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 13056 13057 updatePermissionsLPw(newPkg.packageName, newPkg, 13058 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 13059 13060 if (applyUserRestrictions) { 13061 if (DEBUG_REMOVE) { 13062 Slog.d(TAG, "Propagating install state across reinstall"); 13063 } 13064 for (int i = 0; i < allUserHandles.length; i++) { 13065 if (DEBUG_REMOVE) { 13066 Slog.d(TAG, " user " + allUserHandles[i] 13067 + " => " + perUserInstalled[i]); 13068 } 13069 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 13070 13071 mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false); 13072 } 13073 // Regardless of writeSettings we need to ensure that this restriction 13074 // state propagation is persisted 13075 mSettings.writeAllUsersPackageRestrictionsLPr(); 13076 } 13077 // can downgrade to reader here 13078 if (writeSettings) { 13079 mSettings.writeLPr(); 13080 } 13081 } 13082 return true; 13083 } 13084 13085 private boolean deleteInstalledPackageLI(PackageSetting ps, 13086 boolean deleteCodeAndResources, int flags, 13087 int[] allUserHandles, boolean[] perUserInstalled, 13088 PackageRemovedInfo outInfo, boolean writeSettings) { 13089 if (outInfo != null) { 13090 outInfo.uid = ps.appId; 13091 } 13092 13093 // Delete package data from internal structures and also remove data if flag is set 13094 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 13095 13096 // Delete application code and resources 13097 if (deleteCodeAndResources && (outInfo != null)) { 13098 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 13099 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 13100 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 13101 } 13102 return true; 13103 } 13104 13105 @Override 13106 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 13107 int userId) { 13108 mContext.enforceCallingOrSelfPermission( 13109 android.Manifest.permission.DELETE_PACKAGES, null); 13110 synchronized (mPackages) { 13111 PackageSetting ps = mSettings.mPackages.get(packageName); 13112 if (ps == null) { 13113 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 13114 return false; 13115 } 13116 if (!ps.getInstalled(userId)) { 13117 // Can't block uninstall for an app that is not installed or enabled. 13118 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 13119 return false; 13120 } 13121 ps.setBlockUninstall(blockUninstall, userId); 13122 mSettings.writePackageRestrictionsLPr(userId); 13123 } 13124 return true; 13125 } 13126 13127 @Override 13128 public boolean getBlockUninstallForUser(String packageName, int userId) { 13129 synchronized (mPackages) { 13130 PackageSetting ps = mSettings.mPackages.get(packageName); 13131 if (ps == null) { 13132 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 13133 return false; 13134 } 13135 return ps.getBlockUninstall(userId); 13136 } 13137 } 13138 13139 /* 13140 * This method handles package deletion in general 13141 */ 13142 private boolean deletePackageLI(String packageName, UserHandle user, 13143 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 13144 int flags, PackageRemovedInfo outInfo, 13145 boolean writeSettings) { 13146 if (packageName == null) { 13147 Slog.w(TAG, "Attempt to delete null packageName."); 13148 return false; 13149 } 13150 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 13151 PackageSetting ps; 13152 boolean dataOnly = false; 13153 int removeUser = -1; 13154 int appId = -1; 13155 synchronized (mPackages) { 13156 ps = mSettings.mPackages.get(packageName); 13157 if (ps == null) { 13158 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 13159 return false; 13160 } 13161 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 13162 && user.getIdentifier() != UserHandle.USER_ALL) { 13163 // The caller is asking that the package only be deleted for a single 13164 // user. To do this, we just mark its uninstalled state and delete 13165 // its data. If this is a system app, we only allow this to happen if 13166 // they have set the special DELETE_SYSTEM_APP which requests different 13167 // semantics than normal for uninstalling system apps. 13168 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 13169 ps.setUserState(user.getIdentifier(), 13170 COMPONENT_ENABLED_STATE_DEFAULT, 13171 false, //installed 13172 true, //stopped 13173 true, //notLaunched 13174 false, //hidden 13175 null, null, null, 13176 false, // blockUninstall 13177 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0); 13178 if (!isSystemApp(ps)) { 13179 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 13180 // Other user still have this package installed, so all 13181 // we need to do is clear this user's data and save that 13182 // it is uninstalled. 13183 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 13184 removeUser = user.getIdentifier(); 13185 appId = ps.appId; 13186 scheduleWritePackageRestrictionsLocked(removeUser); 13187 } else { 13188 // We need to set it back to 'installed' so the uninstall 13189 // broadcasts will be sent correctly. 13190 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 13191 ps.setInstalled(true, user.getIdentifier()); 13192 } 13193 } else { 13194 // This is a system app, so we assume that the 13195 // other users still have this package installed, so all 13196 // we need to do is clear this user's data and save that 13197 // it is uninstalled. 13198 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 13199 removeUser = user.getIdentifier(); 13200 appId = ps.appId; 13201 scheduleWritePackageRestrictionsLocked(removeUser); 13202 } 13203 } 13204 } 13205 13206 if (removeUser >= 0) { 13207 // From above, we determined that we are deleting this only 13208 // for a single user. Continue the work here. 13209 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 13210 if (outInfo != null) { 13211 outInfo.removedPackage = packageName; 13212 outInfo.removedAppId = appId; 13213 outInfo.removedUsers = new int[] {removeUser}; 13214 } 13215 mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser); 13216 removeKeystoreDataIfNeeded(removeUser, appId); 13217 schedulePackageCleaning(packageName, removeUser, false); 13218 synchronized (mPackages) { 13219 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { 13220 scheduleWritePackageRestrictionsLocked(removeUser); 13221 } 13222 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser); 13223 } 13224 return true; 13225 } 13226 13227 if (dataOnly) { 13228 // Delete application data first 13229 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 13230 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 13231 return true; 13232 } 13233 13234 boolean ret = false; 13235 if (isSystemApp(ps)) { 13236 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 13237 // When an updated system application is deleted we delete the existing resources as well and 13238 // fall back to existing code in system partition 13239 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 13240 flags, outInfo, writeSettings); 13241 } else { 13242 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 13243 // Kill application pre-emptively especially for apps on sd. 13244 killApplication(packageName, ps.appId, "uninstall pkg"); 13245 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 13246 allUserHandles, perUserInstalled, 13247 outInfo, writeSettings); 13248 } 13249 13250 return ret; 13251 } 13252 13253 private final class ClearStorageConnection implements ServiceConnection { 13254 IMediaContainerService mContainerService; 13255 13256 @Override 13257 public void onServiceConnected(ComponentName name, IBinder service) { 13258 synchronized (this) { 13259 mContainerService = IMediaContainerService.Stub.asInterface(service); 13260 notifyAll(); 13261 } 13262 } 13263 13264 @Override 13265 public void onServiceDisconnected(ComponentName name) { 13266 } 13267 } 13268 13269 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 13270 final boolean mounted; 13271 if (Environment.isExternalStorageEmulated()) { 13272 mounted = true; 13273 } else { 13274 final String status = Environment.getExternalStorageState(); 13275 13276 mounted = status.equals(Environment.MEDIA_MOUNTED) 13277 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 13278 } 13279 13280 if (!mounted) { 13281 return; 13282 } 13283 13284 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 13285 int[] users; 13286 if (userId == UserHandle.USER_ALL) { 13287 users = sUserManager.getUserIds(); 13288 } else { 13289 users = new int[] { userId }; 13290 } 13291 final ClearStorageConnection conn = new ClearStorageConnection(); 13292 if (mContext.bindServiceAsUser( 13293 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 13294 try { 13295 for (int curUser : users) { 13296 long timeout = SystemClock.uptimeMillis() + 5000; 13297 synchronized (conn) { 13298 long now = SystemClock.uptimeMillis(); 13299 while (conn.mContainerService == null && now < timeout) { 13300 try { 13301 conn.wait(timeout - now); 13302 } catch (InterruptedException e) { 13303 } 13304 } 13305 } 13306 if (conn.mContainerService == null) { 13307 return; 13308 } 13309 13310 final UserEnvironment userEnv = new UserEnvironment(curUser); 13311 clearDirectory(conn.mContainerService, 13312 userEnv.buildExternalStorageAppCacheDirs(packageName)); 13313 if (allData) { 13314 clearDirectory(conn.mContainerService, 13315 userEnv.buildExternalStorageAppDataDirs(packageName)); 13316 clearDirectory(conn.mContainerService, 13317 userEnv.buildExternalStorageAppMediaDirs(packageName)); 13318 } 13319 } 13320 } finally { 13321 mContext.unbindService(conn); 13322 } 13323 } 13324 } 13325 13326 @Override 13327 public void clearApplicationUserData(final String packageName, 13328 final IPackageDataObserver observer, final int userId) { 13329 mContext.enforceCallingOrSelfPermission( 13330 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 13331 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 13332 // Queue up an async operation since the package deletion may take a little while. 13333 mHandler.post(new Runnable() { 13334 public void run() { 13335 mHandler.removeCallbacks(this); 13336 final boolean succeeded; 13337 synchronized (mInstallLock) { 13338 succeeded = clearApplicationUserDataLI(packageName, userId); 13339 } 13340 clearExternalStorageDataSync(packageName, userId, true); 13341 if (succeeded) { 13342 // invoke DeviceStorageMonitor's update method to clear any notifications 13343 DeviceStorageMonitorInternal 13344 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 13345 if (dsm != null) { 13346 dsm.checkMemory(); 13347 } 13348 } 13349 if(observer != null) { 13350 try { 13351 observer.onRemoveCompleted(packageName, succeeded); 13352 } catch (RemoteException e) { 13353 Log.i(TAG, "Observer no longer exists."); 13354 } 13355 } //end if observer 13356 } //end run 13357 }); 13358 } 13359 13360 private boolean clearApplicationUserDataLI(String packageName, int userId) { 13361 if (packageName == null) { 13362 Slog.w(TAG, "Attempt to delete null packageName."); 13363 return false; 13364 } 13365 13366 // Try finding details about the requested package 13367 PackageParser.Package pkg; 13368 synchronized (mPackages) { 13369 pkg = mPackages.get(packageName); 13370 if (pkg == null) { 13371 final PackageSetting ps = mSettings.mPackages.get(packageName); 13372 if (ps != null) { 13373 pkg = ps.pkg; 13374 } 13375 } 13376 13377 if (pkg == null) { 13378 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 13379 return false; 13380 } 13381 13382 PackageSetting ps = (PackageSetting) pkg.mExtras; 13383 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 13384 } 13385 13386 // Always delete data directories for package, even if we found no other 13387 // record of app. This helps users recover from UID mismatches without 13388 // resorting to a full data wipe. 13389 int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId); 13390 if (retCode < 0) { 13391 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 13392 return false; 13393 } 13394 13395 final int appId = pkg.applicationInfo.uid; 13396 removeKeystoreDataIfNeeded(userId, appId); 13397 13398 // Create a native library symlink only if we have native libraries 13399 // and if the native libraries are 32 bit libraries. We do not provide 13400 // this symlink for 64 bit libraries. 13401 if (pkg.applicationInfo.primaryCpuAbi != null && 13402 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 13403 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 13404 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 13405 nativeLibPath, userId) < 0) { 13406 Slog.w(TAG, "Failed linking native library dir"); 13407 return false; 13408 } 13409 } 13410 13411 return true; 13412 } 13413 13414 /** 13415 * Reverts user permission state changes (permissions and flags) in 13416 * all packages for a given user. 13417 * 13418 * @param userId The device user for which to do a reset. 13419 */ 13420 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 13421 final int packageCount = mPackages.size(); 13422 for (int i = 0; i < packageCount; i++) { 13423 PackageParser.Package pkg = mPackages.valueAt(i); 13424 PackageSetting ps = (PackageSetting) pkg.mExtras; 13425 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 13426 } 13427 } 13428 13429 /** 13430 * Reverts user permission state changes (permissions and flags). 13431 * 13432 * @param ps The package for which to reset. 13433 * @param userId The device user for which to do a reset. 13434 */ 13435 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 13436 final PackageSetting ps, final int userId) { 13437 if (ps.pkg == null) { 13438 return; 13439 } 13440 13441 final int userSettableFlags = FLAG_PERMISSION_USER_SET 13442 | FLAG_PERMISSION_USER_FIXED 13443 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 13444 13445 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 13446 | FLAG_PERMISSION_POLICY_FIXED; 13447 13448 boolean writeInstallPermissions = false; 13449 boolean writeRuntimePermissions = false; 13450 13451 final int permissionCount = ps.pkg.requestedPermissions.size(); 13452 for (int i = 0; i < permissionCount; i++) { 13453 String permission = ps.pkg.requestedPermissions.get(i); 13454 13455 BasePermission bp = mSettings.mPermissions.get(permission); 13456 if (bp == null) { 13457 continue; 13458 } 13459 13460 // If shared user we just reset the state to which only this app contributed. 13461 if (ps.sharedUser != null) { 13462 boolean used = false; 13463 final int packageCount = ps.sharedUser.packages.size(); 13464 for (int j = 0; j < packageCount; j++) { 13465 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 13466 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 13467 && pkg.pkg.requestedPermissions.contains(permission)) { 13468 used = true; 13469 break; 13470 } 13471 } 13472 if (used) { 13473 continue; 13474 } 13475 } 13476 13477 PermissionsState permissionsState = ps.getPermissionsState(); 13478 13479 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 13480 13481 // Always clear the user settable flags. 13482 final boolean hasInstallState = permissionsState.getInstallPermissionState( 13483 bp.name) != null; 13484 if (permissionsState.updatePermissionFlags(bp, userId, userSettableFlags, 0)) { 13485 if (hasInstallState) { 13486 writeInstallPermissions = true; 13487 } else { 13488 writeRuntimePermissions = true; 13489 } 13490 } 13491 13492 // Below is only runtime permission handling. 13493 if (!bp.isRuntime()) { 13494 continue; 13495 } 13496 13497 // Never clobber system or policy. 13498 if ((oldFlags & policyOrSystemFlags) != 0) { 13499 continue; 13500 } 13501 13502 // If this permission was granted by default, make sure it is. 13503 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 13504 if (permissionsState.grantRuntimePermission(bp, userId) 13505 != PERMISSION_OPERATION_FAILURE) { 13506 writeRuntimePermissions = true; 13507 } 13508 } else { 13509 // Otherwise, reset the permission. 13510 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 13511 switch (revokeResult) { 13512 case PERMISSION_OPERATION_SUCCESS: { 13513 writeRuntimePermissions = true; 13514 } break; 13515 13516 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 13517 writeRuntimePermissions = true; 13518 // If gids changed for this user, kill all affected packages. 13519 mHandler.post(new Runnable() { 13520 @Override 13521 public void run() { 13522 // This has to happen with no lock held. 13523 killSettingPackagesForUser(ps, userId, 13524 KILL_APP_REASON_GIDS_CHANGED); 13525 } 13526 }); 13527 } break; 13528 } 13529 } 13530 } 13531 13532 // Synchronously write as we are taking permissions away. 13533 if (writeRuntimePermissions) { 13534 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 13535 } 13536 13537 // Synchronously write as we are taking permissions away. 13538 if (writeInstallPermissions) { 13539 mSettings.writeLPr(); 13540 } 13541 } 13542 13543 /** 13544 * Remove entries from the keystore daemon. Will only remove it if the 13545 * {@code appId} is valid. 13546 */ 13547 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 13548 if (appId < 0) { 13549 return; 13550 } 13551 13552 final KeyStore keyStore = KeyStore.getInstance(); 13553 if (keyStore != null) { 13554 if (userId == UserHandle.USER_ALL) { 13555 for (final int individual : sUserManager.getUserIds()) { 13556 keyStore.clearUid(UserHandle.getUid(individual, appId)); 13557 } 13558 } else { 13559 keyStore.clearUid(UserHandle.getUid(userId, appId)); 13560 } 13561 } else { 13562 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 13563 } 13564 } 13565 13566 @Override 13567 public void deleteApplicationCacheFiles(final String packageName, 13568 final IPackageDataObserver observer) { 13569 mContext.enforceCallingOrSelfPermission( 13570 android.Manifest.permission.DELETE_CACHE_FILES, null); 13571 // Queue up an async operation since the package deletion may take a little while. 13572 final int userId = UserHandle.getCallingUserId(); 13573 mHandler.post(new Runnable() { 13574 public void run() { 13575 mHandler.removeCallbacks(this); 13576 final boolean succeded; 13577 synchronized (mInstallLock) { 13578 succeded = deleteApplicationCacheFilesLI(packageName, userId); 13579 } 13580 clearExternalStorageDataSync(packageName, userId, false); 13581 if (observer != null) { 13582 try { 13583 observer.onRemoveCompleted(packageName, succeded); 13584 } catch (RemoteException e) { 13585 Log.i(TAG, "Observer no longer exists."); 13586 } 13587 } //end if observer 13588 } //end run 13589 }); 13590 } 13591 13592 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 13593 if (packageName == null) { 13594 Slog.w(TAG, "Attempt to delete null packageName."); 13595 return false; 13596 } 13597 PackageParser.Package p; 13598 synchronized (mPackages) { 13599 p = mPackages.get(packageName); 13600 } 13601 if (p == null) { 13602 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 13603 return false; 13604 } 13605 final ApplicationInfo applicationInfo = p.applicationInfo; 13606 if (applicationInfo == null) { 13607 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 13608 return false; 13609 } 13610 int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId); 13611 if (retCode < 0) { 13612 Slog.w(TAG, "Couldn't remove cache files for package: " 13613 + packageName + " u" + userId); 13614 return false; 13615 } 13616 return true; 13617 } 13618 13619 @Override 13620 public void getPackageSizeInfo(final String packageName, int userHandle, 13621 final IPackageStatsObserver observer) { 13622 mContext.enforceCallingOrSelfPermission( 13623 android.Manifest.permission.GET_PACKAGE_SIZE, null); 13624 if (packageName == null) { 13625 throw new IllegalArgumentException("Attempt to get size of null packageName"); 13626 } 13627 13628 PackageStats stats = new PackageStats(packageName, userHandle); 13629 13630 /* 13631 * Queue up an async operation since the package measurement may take a 13632 * little while. 13633 */ 13634 Message msg = mHandler.obtainMessage(INIT_COPY); 13635 msg.obj = new MeasureParams(stats, observer); 13636 mHandler.sendMessage(msg); 13637 } 13638 13639 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 13640 PackageStats pStats) { 13641 if (packageName == null) { 13642 Slog.w(TAG, "Attempt to get size of null packageName."); 13643 return false; 13644 } 13645 PackageParser.Package p; 13646 boolean dataOnly = false; 13647 String libDirRoot = null; 13648 String asecPath = null; 13649 PackageSetting ps = null; 13650 synchronized (mPackages) { 13651 p = mPackages.get(packageName); 13652 ps = mSettings.mPackages.get(packageName); 13653 if(p == null) { 13654 dataOnly = true; 13655 if((ps == null) || (ps.pkg == null)) { 13656 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 13657 return false; 13658 } 13659 p = ps.pkg; 13660 } 13661 if (ps != null) { 13662 libDirRoot = ps.legacyNativeLibraryPathString; 13663 } 13664 if (p != null && (isExternal(p) || p.isForwardLocked())) { 13665 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 13666 if (secureContainerId != null) { 13667 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 13668 } 13669 } 13670 } 13671 String publicSrcDir = null; 13672 if(!dataOnly) { 13673 final ApplicationInfo applicationInfo = p.applicationInfo; 13674 if (applicationInfo == null) { 13675 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 13676 return false; 13677 } 13678 if (p.isForwardLocked()) { 13679 publicSrcDir = applicationInfo.getBaseResourcePath(); 13680 } 13681 } 13682 // TODO: extend to measure size of split APKs 13683 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 13684 // not just the first level. 13685 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 13686 // just the primary. 13687 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 13688 int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath, 13689 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 13690 if (res < 0) { 13691 return false; 13692 } 13693 13694 // Fix-up for forward-locked applications in ASEC containers. 13695 if (!isExternal(p)) { 13696 pStats.codeSize += pStats.externalCodeSize; 13697 pStats.externalCodeSize = 0L; 13698 } 13699 13700 return true; 13701 } 13702 13703 13704 @Override 13705 public void addPackageToPreferred(String packageName) { 13706 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 13707 } 13708 13709 @Override 13710 public void removePackageFromPreferred(String packageName) { 13711 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 13712 } 13713 13714 @Override 13715 public List<PackageInfo> getPreferredPackages(int flags) { 13716 return new ArrayList<PackageInfo>(); 13717 } 13718 13719 private int getUidTargetSdkVersionLockedLPr(int uid) { 13720 Object obj = mSettings.getUserIdLPr(uid); 13721 if (obj instanceof SharedUserSetting) { 13722 final SharedUserSetting sus = (SharedUserSetting) obj; 13723 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 13724 final Iterator<PackageSetting> it = sus.packages.iterator(); 13725 while (it.hasNext()) { 13726 final PackageSetting ps = it.next(); 13727 if (ps.pkg != null) { 13728 int v = ps.pkg.applicationInfo.targetSdkVersion; 13729 if (v < vers) vers = v; 13730 } 13731 } 13732 return vers; 13733 } else if (obj instanceof PackageSetting) { 13734 final PackageSetting ps = (PackageSetting) obj; 13735 if (ps.pkg != null) { 13736 return ps.pkg.applicationInfo.targetSdkVersion; 13737 } 13738 } 13739 return Build.VERSION_CODES.CUR_DEVELOPMENT; 13740 } 13741 13742 @Override 13743 public void addPreferredActivity(IntentFilter filter, int match, 13744 ComponentName[] set, ComponentName activity, int userId) { 13745 addPreferredActivityInternal(filter, match, set, activity, true, userId, 13746 "Adding preferred"); 13747 } 13748 13749 private void addPreferredActivityInternal(IntentFilter filter, int match, 13750 ComponentName[] set, ComponentName activity, boolean always, int userId, 13751 String opname) { 13752 // writer 13753 int callingUid = Binder.getCallingUid(); 13754 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 13755 if (filter.countActions() == 0) { 13756 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 13757 return; 13758 } 13759 synchronized (mPackages) { 13760 if (mContext.checkCallingOrSelfPermission( 13761 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 13762 != PackageManager.PERMISSION_GRANTED) { 13763 if (getUidTargetSdkVersionLockedLPr(callingUid) 13764 < Build.VERSION_CODES.FROYO) { 13765 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 13766 + callingUid); 13767 return; 13768 } 13769 mContext.enforceCallingOrSelfPermission( 13770 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13771 } 13772 13773 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 13774 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 13775 + userId + ":"); 13776 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13777 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 13778 scheduleWritePackageRestrictionsLocked(userId); 13779 } 13780 } 13781 13782 @Override 13783 public void replacePreferredActivity(IntentFilter filter, int match, 13784 ComponentName[] set, ComponentName activity, int userId) { 13785 if (filter.countActions() != 1) { 13786 throw new IllegalArgumentException( 13787 "replacePreferredActivity expects filter to have only 1 action."); 13788 } 13789 if (filter.countDataAuthorities() != 0 13790 || filter.countDataPaths() != 0 13791 || filter.countDataSchemes() > 1 13792 || filter.countDataTypes() != 0) { 13793 throw new IllegalArgumentException( 13794 "replacePreferredActivity expects filter to have no data authorities, " + 13795 "paths, or types; and at most one scheme."); 13796 } 13797 13798 final int callingUid = Binder.getCallingUid(); 13799 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 13800 synchronized (mPackages) { 13801 if (mContext.checkCallingOrSelfPermission( 13802 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 13803 != PackageManager.PERMISSION_GRANTED) { 13804 if (getUidTargetSdkVersionLockedLPr(callingUid) 13805 < Build.VERSION_CODES.FROYO) { 13806 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 13807 + Binder.getCallingUid()); 13808 return; 13809 } 13810 mContext.enforceCallingOrSelfPermission( 13811 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13812 } 13813 13814 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 13815 if (pir != null) { 13816 // Get all of the existing entries that exactly match this filter. 13817 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 13818 if (existing != null && existing.size() == 1) { 13819 PreferredActivity cur = existing.get(0); 13820 if (DEBUG_PREFERRED) { 13821 Slog.i(TAG, "Checking replace of preferred:"); 13822 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13823 if (!cur.mPref.mAlways) { 13824 Slog.i(TAG, " -- CUR; not mAlways!"); 13825 } else { 13826 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 13827 Slog.i(TAG, " -- CUR: mSet=" 13828 + Arrays.toString(cur.mPref.mSetComponents)); 13829 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 13830 Slog.i(TAG, " -- NEW: mMatch=" 13831 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 13832 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 13833 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 13834 } 13835 } 13836 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 13837 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 13838 && cur.mPref.sameSet(set)) { 13839 // Setting the preferred activity to what it happens to be already 13840 if (DEBUG_PREFERRED) { 13841 Slog.i(TAG, "Replacing with same preferred activity " 13842 + cur.mPref.mShortComponent + " for user " 13843 + userId + ":"); 13844 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13845 } 13846 return; 13847 } 13848 } 13849 13850 if (existing != null) { 13851 if (DEBUG_PREFERRED) { 13852 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 13853 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13854 } 13855 for (int i = 0; i < existing.size(); i++) { 13856 PreferredActivity pa = existing.get(i); 13857 if (DEBUG_PREFERRED) { 13858 Slog.i(TAG, "Removing existing preferred activity " 13859 + pa.mPref.mComponent + ":"); 13860 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 13861 } 13862 pir.removeFilter(pa); 13863 } 13864 } 13865 } 13866 addPreferredActivityInternal(filter, match, set, activity, true, userId, 13867 "Replacing preferred"); 13868 } 13869 } 13870 13871 @Override 13872 public void clearPackagePreferredActivities(String packageName) { 13873 final int uid = Binder.getCallingUid(); 13874 // writer 13875 synchronized (mPackages) { 13876 PackageParser.Package pkg = mPackages.get(packageName); 13877 if (pkg == null || pkg.applicationInfo.uid != uid) { 13878 if (mContext.checkCallingOrSelfPermission( 13879 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 13880 != PackageManager.PERMISSION_GRANTED) { 13881 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 13882 < Build.VERSION_CODES.FROYO) { 13883 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 13884 + Binder.getCallingUid()); 13885 return; 13886 } 13887 mContext.enforceCallingOrSelfPermission( 13888 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13889 } 13890 } 13891 13892 int user = UserHandle.getCallingUserId(); 13893 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 13894 scheduleWritePackageRestrictionsLocked(user); 13895 } 13896 } 13897 } 13898 13899 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 13900 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 13901 ArrayList<PreferredActivity> removed = null; 13902 boolean changed = false; 13903 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13904 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 13905 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13906 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 13907 continue; 13908 } 13909 Iterator<PreferredActivity> it = pir.filterIterator(); 13910 while (it.hasNext()) { 13911 PreferredActivity pa = it.next(); 13912 // Mark entry for removal only if it matches the package name 13913 // and the entry is of type "always". 13914 if (packageName == null || 13915 (pa.mPref.mComponent.getPackageName().equals(packageName) 13916 && pa.mPref.mAlways)) { 13917 if (removed == null) { 13918 removed = new ArrayList<PreferredActivity>(); 13919 } 13920 removed.add(pa); 13921 } 13922 } 13923 if (removed != null) { 13924 for (int j=0; j<removed.size(); j++) { 13925 PreferredActivity pa = removed.get(j); 13926 pir.removeFilter(pa); 13927 } 13928 changed = true; 13929 } 13930 } 13931 return changed; 13932 } 13933 13934 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 13935 private void clearIntentFilterVerificationsLPw(int userId) { 13936 final int packageCount = mPackages.size(); 13937 for (int i = 0; i < packageCount; i++) { 13938 PackageParser.Package pkg = mPackages.valueAt(i); 13939 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 13940 } 13941 } 13942 13943 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 13944 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 13945 if (userId == UserHandle.USER_ALL) { 13946 if (mSettings.removeIntentFilterVerificationLPw(packageName, 13947 sUserManager.getUserIds())) { 13948 for (int oneUserId : sUserManager.getUserIds()) { 13949 scheduleWritePackageRestrictionsLocked(oneUserId); 13950 } 13951 } 13952 } else { 13953 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 13954 scheduleWritePackageRestrictionsLocked(userId); 13955 } 13956 } 13957 } 13958 13959 void clearDefaultBrowserIfNeeded(String packageName) { 13960 for (int oneUserId : sUserManager.getUserIds()) { 13961 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 13962 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 13963 if (packageName.equals(defaultBrowserPackageName)) { 13964 setDefaultBrowserPackageName(null, oneUserId); 13965 } 13966 } 13967 } 13968 13969 @Override 13970 public void resetApplicationPreferences(int userId) { 13971 mContext.enforceCallingOrSelfPermission( 13972 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13973 // writer 13974 synchronized (mPackages) { 13975 final long identity = Binder.clearCallingIdentity(); 13976 try { 13977 clearPackagePreferredActivitiesLPw(null, userId); 13978 mSettings.applyDefaultPreferredAppsLPw(this, userId); 13979 // TODO: We have to reset the default SMS and Phone. This requires 13980 // significant refactoring to keep all default apps in the package 13981 // manager (cleaner but more work) or have the services provide 13982 // callbacks to the package manager to request a default app reset. 13983 applyFactoryDefaultBrowserLPw(userId); 13984 clearIntentFilterVerificationsLPw(userId); 13985 primeDomainVerificationsLPw(userId); 13986 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 13987 scheduleWritePackageRestrictionsLocked(userId); 13988 } finally { 13989 Binder.restoreCallingIdentity(identity); 13990 } 13991 } 13992 } 13993 13994 @Override 13995 public int getPreferredActivities(List<IntentFilter> outFilters, 13996 List<ComponentName> outActivities, String packageName) { 13997 13998 int num = 0; 13999 final int userId = UserHandle.getCallingUserId(); 14000 // reader 14001 synchronized (mPackages) { 14002 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 14003 if (pir != null) { 14004 final Iterator<PreferredActivity> it = pir.filterIterator(); 14005 while (it.hasNext()) { 14006 final PreferredActivity pa = it.next(); 14007 if (packageName == null 14008 || (pa.mPref.mComponent.getPackageName().equals(packageName) 14009 && pa.mPref.mAlways)) { 14010 if (outFilters != null) { 14011 outFilters.add(new IntentFilter(pa)); 14012 } 14013 if (outActivities != null) { 14014 outActivities.add(pa.mPref.mComponent); 14015 } 14016 } 14017 } 14018 } 14019 } 14020 14021 return num; 14022 } 14023 14024 @Override 14025 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 14026 int userId) { 14027 int callingUid = Binder.getCallingUid(); 14028 if (callingUid != Process.SYSTEM_UID) { 14029 throw new SecurityException( 14030 "addPersistentPreferredActivity can only be run by the system"); 14031 } 14032 if (filter.countActions() == 0) { 14033 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 14034 return; 14035 } 14036 synchronized (mPackages) { 14037 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 14038 " :"); 14039 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14040 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 14041 new PersistentPreferredActivity(filter, activity)); 14042 scheduleWritePackageRestrictionsLocked(userId); 14043 } 14044 } 14045 14046 @Override 14047 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 14048 int callingUid = Binder.getCallingUid(); 14049 if (callingUid != Process.SYSTEM_UID) { 14050 throw new SecurityException( 14051 "clearPackagePersistentPreferredActivities can only be run by the system"); 14052 } 14053 ArrayList<PersistentPreferredActivity> removed = null; 14054 boolean changed = false; 14055 synchronized (mPackages) { 14056 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 14057 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 14058 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 14059 .valueAt(i); 14060 if (userId != thisUserId) { 14061 continue; 14062 } 14063 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 14064 while (it.hasNext()) { 14065 PersistentPreferredActivity ppa = it.next(); 14066 // Mark entry for removal only if it matches the package name. 14067 if (ppa.mComponent.getPackageName().equals(packageName)) { 14068 if (removed == null) { 14069 removed = new ArrayList<PersistentPreferredActivity>(); 14070 } 14071 removed.add(ppa); 14072 } 14073 } 14074 if (removed != null) { 14075 for (int j=0; j<removed.size(); j++) { 14076 PersistentPreferredActivity ppa = removed.get(j); 14077 ppir.removeFilter(ppa); 14078 } 14079 changed = true; 14080 } 14081 } 14082 14083 if (changed) { 14084 scheduleWritePackageRestrictionsLocked(userId); 14085 } 14086 } 14087 } 14088 14089 /** 14090 * Common machinery for picking apart a restored XML blob and passing 14091 * it to a caller-supplied functor to be applied to the running system. 14092 */ 14093 private void restoreFromXml(XmlPullParser parser, int userId, 14094 String expectedStartTag, BlobXmlRestorer functor) 14095 throws IOException, XmlPullParserException { 14096 int type; 14097 while ((type = parser.next()) != XmlPullParser.START_TAG 14098 && type != XmlPullParser.END_DOCUMENT) { 14099 } 14100 if (type != XmlPullParser.START_TAG) { 14101 // oops didn't find a start tag?! 14102 if (DEBUG_BACKUP) { 14103 Slog.e(TAG, "Didn't find start tag during restore"); 14104 } 14105 return; 14106 } 14107 14108 // this is supposed to be TAG_PREFERRED_BACKUP 14109 if (!expectedStartTag.equals(parser.getName())) { 14110 if (DEBUG_BACKUP) { 14111 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 14112 } 14113 return; 14114 } 14115 14116 // skip interfering stuff, then we're aligned with the backing implementation 14117 while ((type = parser.next()) == XmlPullParser.TEXT) { } 14118 functor.apply(parser, userId); 14119 } 14120 14121 private interface BlobXmlRestorer { 14122 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 14123 } 14124 14125 /** 14126 * Non-Binder method, support for the backup/restore mechanism: write the 14127 * full set of preferred activities in its canonical XML format. Returns the 14128 * XML output as a byte array, or null if there is none. 14129 */ 14130 @Override 14131 public byte[] getPreferredActivityBackup(int userId) { 14132 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14133 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 14134 } 14135 14136 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14137 try { 14138 final XmlSerializer serializer = new FastXmlSerializer(); 14139 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14140 serializer.startDocument(null, true); 14141 serializer.startTag(null, TAG_PREFERRED_BACKUP); 14142 14143 synchronized (mPackages) { 14144 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 14145 } 14146 14147 serializer.endTag(null, TAG_PREFERRED_BACKUP); 14148 serializer.endDocument(); 14149 serializer.flush(); 14150 } catch (Exception e) { 14151 if (DEBUG_BACKUP) { 14152 Slog.e(TAG, "Unable to write preferred activities for backup", e); 14153 } 14154 return null; 14155 } 14156 14157 return dataStream.toByteArray(); 14158 } 14159 14160 @Override 14161 public void restorePreferredActivities(byte[] backup, int userId) { 14162 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14163 throw new SecurityException("Only the system may call restorePreferredActivities()"); 14164 } 14165 14166 try { 14167 final XmlPullParser parser = Xml.newPullParser(); 14168 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14169 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 14170 new BlobXmlRestorer() { 14171 @Override 14172 public void apply(XmlPullParser parser, int userId) 14173 throws XmlPullParserException, IOException { 14174 synchronized (mPackages) { 14175 mSettings.readPreferredActivitiesLPw(parser, userId); 14176 } 14177 } 14178 } ); 14179 } catch (Exception e) { 14180 if (DEBUG_BACKUP) { 14181 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 14182 } 14183 } 14184 } 14185 14186 /** 14187 * Non-Binder method, support for the backup/restore mechanism: write the 14188 * default browser (etc) settings in its canonical XML format. Returns the default 14189 * browser XML representation as a byte array, or null if there is none. 14190 */ 14191 @Override 14192 public byte[] getDefaultAppsBackup(int userId) { 14193 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14194 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 14195 } 14196 14197 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14198 try { 14199 final XmlSerializer serializer = new FastXmlSerializer(); 14200 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14201 serializer.startDocument(null, true); 14202 serializer.startTag(null, TAG_DEFAULT_APPS); 14203 14204 synchronized (mPackages) { 14205 mSettings.writeDefaultAppsLPr(serializer, userId); 14206 } 14207 14208 serializer.endTag(null, TAG_DEFAULT_APPS); 14209 serializer.endDocument(); 14210 serializer.flush(); 14211 } catch (Exception e) { 14212 if (DEBUG_BACKUP) { 14213 Slog.e(TAG, "Unable to write default apps for backup", e); 14214 } 14215 return null; 14216 } 14217 14218 return dataStream.toByteArray(); 14219 } 14220 14221 @Override 14222 public void restoreDefaultApps(byte[] backup, int userId) { 14223 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14224 throw new SecurityException("Only the system may call restoreDefaultApps()"); 14225 } 14226 14227 try { 14228 final XmlPullParser parser = Xml.newPullParser(); 14229 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14230 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 14231 new BlobXmlRestorer() { 14232 @Override 14233 public void apply(XmlPullParser parser, int userId) 14234 throws XmlPullParserException, IOException { 14235 synchronized (mPackages) { 14236 mSettings.readDefaultAppsLPw(parser, userId); 14237 } 14238 } 14239 } ); 14240 } catch (Exception e) { 14241 if (DEBUG_BACKUP) { 14242 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 14243 } 14244 } 14245 } 14246 14247 @Override 14248 public byte[] getIntentFilterVerificationBackup(int userId) { 14249 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14250 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 14251 } 14252 14253 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14254 try { 14255 final XmlSerializer serializer = new FastXmlSerializer(); 14256 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14257 serializer.startDocument(null, true); 14258 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 14259 14260 synchronized (mPackages) { 14261 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 14262 } 14263 14264 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 14265 serializer.endDocument(); 14266 serializer.flush(); 14267 } catch (Exception e) { 14268 if (DEBUG_BACKUP) { 14269 Slog.e(TAG, "Unable to write default apps for backup", e); 14270 } 14271 return null; 14272 } 14273 14274 return dataStream.toByteArray(); 14275 } 14276 14277 @Override 14278 public void restoreIntentFilterVerification(byte[] backup, int userId) { 14279 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14280 throw new SecurityException("Only the system may call restorePreferredActivities()"); 14281 } 14282 14283 try { 14284 final XmlPullParser parser = Xml.newPullParser(); 14285 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14286 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 14287 new BlobXmlRestorer() { 14288 @Override 14289 public void apply(XmlPullParser parser, int userId) 14290 throws XmlPullParserException, IOException { 14291 synchronized (mPackages) { 14292 mSettings.readAllDomainVerificationsLPr(parser, userId); 14293 mSettings.writeLPr(); 14294 } 14295 } 14296 } ); 14297 } catch (Exception e) { 14298 if (DEBUG_BACKUP) { 14299 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 14300 } 14301 } 14302 } 14303 14304 @Override 14305 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 14306 int sourceUserId, int targetUserId, int flags) { 14307 mContext.enforceCallingOrSelfPermission( 14308 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 14309 int callingUid = Binder.getCallingUid(); 14310 enforceOwnerRights(ownerPackage, callingUid); 14311 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 14312 if (intentFilter.countActions() == 0) { 14313 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 14314 return; 14315 } 14316 synchronized (mPackages) { 14317 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 14318 ownerPackage, targetUserId, flags); 14319 CrossProfileIntentResolver resolver = 14320 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 14321 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 14322 // We have all those whose filter is equal. Now checking if the rest is equal as well. 14323 if (existing != null) { 14324 int size = existing.size(); 14325 for (int i = 0; i < size; i++) { 14326 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 14327 return; 14328 } 14329 } 14330 } 14331 resolver.addFilter(newFilter); 14332 scheduleWritePackageRestrictionsLocked(sourceUserId); 14333 } 14334 } 14335 14336 @Override 14337 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 14338 mContext.enforceCallingOrSelfPermission( 14339 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 14340 int callingUid = Binder.getCallingUid(); 14341 enforceOwnerRights(ownerPackage, callingUid); 14342 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 14343 synchronized (mPackages) { 14344 CrossProfileIntentResolver resolver = 14345 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 14346 ArraySet<CrossProfileIntentFilter> set = 14347 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 14348 for (CrossProfileIntentFilter filter : set) { 14349 if (filter.getOwnerPackage().equals(ownerPackage)) { 14350 resolver.removeFilter(filter); 14351 } 14352 } 14353 scheduleWritePackageRestrictionsLocked(sourceUserId); 14354 } 14355 } 14356 14357 // Enforcing that callingUid is owning pkg on userId 14358 private void enforceOwnerRights(String pkg, int callingUid) { 14359 // The system owns everything. 14360 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 14361 return; 14362 } 14363 int callingUserId = UserHandle.getUserId(callingUid); 14364 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 14365 if (pi == null) { 14366 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 14367 + callingUserId); 14368 } 14369 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 14370 throw new SecurityException("Calling uid " + callingUid 14371 + " does not own package " + pkg); 14372 } 14373 } 14374 14375 @Override 14376 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 14377 Intent intent = new Intent(Intent.ACTION_MAIN); 14378 intent.addCategory(Intent.CATEGORY_HOME); 14379 14380 final int callingUserId = UserHandle.getCallingUserId(); 14381 List<ResolveInfo> list = queryIntentActivities(intent, null, 14382 PackageManager.GET_META_DATA, callingUserId); 14383 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 14384 true, false, false, callingUserId); 14385 14386 allHomeCandidates.clear(); 14387 if (list != null) { 14388 for (ResolveInfo ri : list) { 14389 allHomeCandidates.add(ri); 14390 } 14391 } 14392 return (preferred == null || preferred.activityInfo == null) 14393 ? null 14394 : new ComponentName(preferred.activityInfo.packageName, 14395 preferred.activityInfo.name); 14396 } 14397 14398 @Override 14399 public void setApplicationEnabledSetting(String appPackageName, 14400 int newState, int flags, int userId, String callingPackage) { 14401 if (!sUserManager.exists(userId)) return; 14402 if (callingPackage == null) { 14403 callingPackage = Integer.toString(Binder.getCallingUid()); 14404 } 14405 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 14406 } 14407 14408 @Override 14409 public void setComponentEnabledSetting(ComponentName componentName, 14410 int newState, int flags, int userId) { 14411 if (!sUserManager.exists(userId)) return; 14412 setEnabledSetting(componentName.getPackageName(), 14413 componentName.getClassName(), newState, flags, userId, null); 14414 } 14415 14416 private void setEnabledSetting(final String packageName, String className, int newState, 14417 final int flags, int userId, String callingPackage) { 14418 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 14419 || newState == COMPONENT_ENABLED_STATE_ENABLED 14420 || newState == COMPONENT_ENABLED_STATE_DISABLED 14421 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 14422 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 14423 throw new IllegalArgumentException("Invalid new component state: " 14424 + newState); 14425 } 14426 PackageSetting pkgSetting; 14427 final int uid = Binder.getCallingUid(); 14428 final int permission = mContext.checkCallingOrSelfPermission( 14429 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 14430 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 14431 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 14432 boolean sendNow = false; 14433 boolean isApp = (className == null); 14434 String componentName = isApp ? packageName : className; 14435 int packageUid = -1; 14436 ArrayList<String> components; 14437 14438 // writer 14439 synchronized (mPackages) { 14440 pkgSetting = mSettings.mPackages.get(packageName); 14441 if (pkgSetting == null) { 14442 if (className == null) { 14443 throw new IllegalArgumentException( 14444 "Unknown package: " + packageName); 14445 } 14446 throw new IllegalArgumentException( 14447 "Unknown component: " + packageName 14448 + "/" + className); 14449 } 14450 // Allow root and verify that userId is not being specified by a different user 14451 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 14452 throw new SecurityException( 14453 "Permission Denial: attempt to change component state from pid=" 14454 + Binder.getCallingPid() 14455 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 14456 } 14457 if (className == null) { 14458 // We're dealing with an application/package level state change 14459 if (pkgSetting.getEnabled(userId) == newState) { 14460 // Nothing to do 14461 return; 14462 } 14463 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 14464 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 14465 // Don't care about who enables an app. 14466 callingPackage = null; 14467 } 14468 pkgSetting.setEnabled(newState, userId, callingPackage); 14469 // pkgSetting.pkg.mSetEnabled = newState; 14470 } else { 14471 // We're dealing with a component level state change 14472 // First, verify that this is a valid class name. 14473 PackageParser.Package pkg = pkgSetting.pkg; 14474 if (pkg == null || !pkg.hasComponentClassName(className)) { 14475 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 14476 throw new IllegalArgumentException("Component class " + className 14477 + " does not exist in " + packageName); 14478 } else { 14479 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 14480 + className + " does not exist in " + packageName); 14481 } 14482 } 14483 switch (newState) { 14484 case COMPONENT_ENABLED_STATE_ENABLED: 14485 if (!pkgSetting.enableComponentLPw(className, userId)) { 14486 return; 14487 } 14488 break; 14489 case COMPONENT_ENABLED_STATE_DISABLED: 14490 if (!pkgSetting.disableComponentLPw(className, userId)) { 14491 return; 14492 } 14493 break; 14494 case COMPONENT_ENABLED_STATE_DEFAULT: 14495 if (!pkgSetting.restoreComponentLPw(className, userId)) { 14496 return; 14497 } 14498 break; 14499 default: 14500 Slog.e(TAG, "Invalid new component state: " + newState); 14501 return; 14502 } 14503 } 14504 scheduleWritePackageRestrictionsLocked(userId); 14505 components = mPendingBroadcasts.get(userId, packageName); 14506 final boolean newPackage = components == null; 14507 if (newPackage) { 14508 components = new ArrayList<String>(); 14509 } 14510 if (!components.contains(componentName)) { 14511 components.add(componentName); 14512 } 14513 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 14514 sendNow = true; 14515 // Purge entry from pending broadcast list if another one exists already 14516 // since we are sending one right away. 14517 mPendingBroadcasts.remove(userId, packageName); 14518 } else { 14519 if (newPackage) { 14520 mPendingBroadcasts.put(userId, packageName, components); 14521 } 14522 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 14523 // Schedule a message 14524 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 14525 } 14526 } 14527 } 14528 14529 long callingId = Binder.clearCallingIdentity(); 14530 try { 14531 if (sendNow) { 14532 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 14533 sendPackageChangedBroadcast(packageName, 14534 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 14535 } 14536 } finally { 14537 Binder.restoreCallingIdentity(callingId); 14538 } 14539 } 14540 14541 private void sendPackageChangedBroadcast(String packageName, 14542 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 14543 if (DEBUG_INSTALL) 14544 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 14545 + componentNames); 14546 Bundle extras = new Bundle(4); 14547 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 14548 String nameList[] = new String[componentNames.size()]; 14549 componentNames.toArray(nameList); 14550 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 14551 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 14552 extras.putInt(Intent.EXTRA_UID, packageUid); 14553 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 14554 new int[] {UserHandle.getUserId(packageUid)}); 14555 } 14556 14557 @Override 14558 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 14559 if (!sUserManager.exists(userId)) return; 14560 final int uid = Binder.getCallingUid(); 14561 final int permission = mContext.checkCallingOrSelfPermission( 14562 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 14563 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 14564 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 14565 // writer 14566 synchronized (mPackages) { 14567 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 14568 allowedByPermission, uid, userId)) { 14569 scheduleWritePackageRestrictionsLocked(userId); 14570 } 14571 } 14572 } 14573 14574 @Override 14575 public String getInstallerPackageName(String packageName) { 14576 // reader 14577 synchronized (mPackages) { 14578 return mSettings.getInstallerPackageNameLPr(packageName); 14579 } 14580 } 14581 14582 @Override 14583 public int getApplicationEnabledSetting(String packageName, int userId) { 14584 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 14585 int uid = Binder.getCallingUid(); 14586 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 14587 // reader 14588 synchronized (mPackages) { 14589 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 14590 } 14591 } 14592 14593 @Override 14594 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 14595 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 14596 int uid = Binder.getCallingUid(); 14597 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 14598 // reader 14599 synchronized (mPackages) { 14600 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 14601 } 14602 } 14603 14604 @Override 14605 public void enterSafeMode() { 14606 enforceSystemOrRoot("Only the system can request entering safe mode"); 14607 14608 if (!mSystemReady) { 14609 mSafeMode = true; 14610 } 14611 } 14612 14613 @Override 14614 public void systemReady() { 14615 mSystemReady = true; 14616 14617 // Read the compatibilty setting when the system is ready. 14618 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 14619 mContext.getContentResolver(), 14620 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 14621 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 14622 if (DEBUG_SETTINGS) { 14623 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 14624 } 14625 14626 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 14627 14628 synchronized (mPackages) { 14629 // Verify that all of the preferred activity components actually 14630 // exist. It is possible for applications to be updated and at 14631 // that point remove a previously declared activity component that 14632 // had been set as a preferred activity. We try to clean this up 14633 // the next time we encounter that preferred activity, but it is 14634 // possible for the user flow to never be able to return to that 14635 // situation so here we do a sanity check to make sure we haven't 14636 // left any junk around. 14637 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 14638 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 14639 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 14640 removed.clear(); 14641 for (PreferredActivity pa : pir.filterSet()) { 14642 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 14643 removed.add(pa); 14644 } 14645 } 14646 if (removed.size() > 0) { 14647 for (int r=0; r<removed.size(); r++) { 14648 PreferredActivity pa = removed.get(r); 14649 Slog.w(TAG, "Removing dangling preferred activity: " 14650 + pa.mPref.mComponent); 14651 pir.removeFilter(pa); 14652 } 14653 mSettings.writePackageRestrictionsLPr( 14654 mSettings.mPreferredActivities.keyAt(i)); 14655 } 14656 } 14657 14658 for (int userId : UserManagerService.getInstance().getUserIds()) { 14659 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 14660 grantPermissionsUserIds = ArrayUtils.appendInt( 14661 grantPermissionsUserIds, userId); 14662 } 14663 } 14664 } 14665 sUserManager.systemReady(); 14666 14667 // If we upgraded grant all default permissions before kicking off. 14668 for (int userId : grantPermissionsUserIds) { 14669 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 14670 } 14671 14672 // Kick off any messages waiting for system ready 14673 if (mPostSystemReadyMessages != null) { 14674 for (Message msg : mPostSystemReadyMessages) { 14675 msg.sendToTarget(); 14676 } 14677 mPostSystemReadyMessages = null; 14678 } 14679 14680 // Watch for external volumes that come and go over time 14681 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14682 storage.registerListener(mStorageListener); 14683 14684 mInstallerService.systemReady(); 14685 mPackageDexOptimizer.systemReady(); 14686 14687 MountServiceInternal mountServiceInternal = LocalServices.getService( 14688 MountServiceInternal.class); 14689 mountServiceInternal.addExternalStoragePolicy( 14690 new MountServiceInternal.ExternalStorageMountPolicy() { 14691 @Override 14692 public int getMountMode(int uid, String packageName) { 14693 if (Process.isIsolated(uid)) { 14694 return Zygote.MOUNT_EXTERNAL_NONE; 14695 } 14696 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 14697 return Zygote.MOUNT_EXTERNAL_DEFAULT; 14698 } 14699 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 14700 return Zygote.MOUNT_EXTERNAL_DEFAULT; 14701 } 14702 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 14703 return Zygote.MOUNT_EXTERNAL_READ; 14704 } 14705 return Zygote.MOUNT_EXTERNAL_WRITE; 14706 } 14707 14708 @Override 14709 public boolean hasExternalStorage(int uid, String packageName) { 14710 return true; 14711 } 14712 }); 14713 } 14714 14715 @Override 14716 public boolean isSafeMode() { 14717 return mSafeMode; 14718 } 14719 14720 @Override 14721 public boolean hasSystemUidErrors() { 14722 return mHasSystemUidErrors; 14723 } 14724 14725 static String arrayToString(int[] array) { 14726 StringBuffer buf = new StringBuffer(128); 14727 buf.append('['); 14728 if (array != null) { 14729 for (int i=0; i<array.length; i++) { 14730 if (i > 0) buf.append(", "); 14731 buf.append(array[i]); 14732 } 14733 } 14734 buf.append(']'); 14735 return buf.toString(); 14736 } 14737 14738 static class DumpState { 14739 public static final int DUMP_LIBS = 1 << 0; 14740 public static final int DUMP_FEATURES = 1 << 1; 14741 public static final int DUMP_RESOLVERS = 1 << 2; 14742 public static final int DUMP_PERMISSIONS = 1 << 3; 14743 public static final int DUMP_PACKAGES = 1 << 4; 14744 public static final int DUMP_SHARED_USERS = 1 << 5; 14745 public static final int DUMP_MESSAGES = 1 << 6; 14746 public static final int DUMP_PROVIDERS = 1 << 7; 14747 public static final int DUMP_VERIFIERS = 1 << 8; 14748 public static final int DUMP_PREFERRED = 1 << 9; 14749 public static final int DUMP_PREFERRED_XML = 1 << 10; 14750 public static final int DUMP_KEYSETS = 1 << 11; 14751 public static final int DUMP_VERSION = 1 << 12; 14752 public static final int DUMP_INSTALLS = 1 << 13; 14753 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14; 14754 public static final int DUMP_DOMAIN_PREFERRED = 1 << 15; 14755 14756 public static final int OPTION_SHOW_FILTERS = 1 << 0; 14757 14758 private int mTypes; 14759 14760 private int mOptions; 14761 14762 private boolean mTitlePrinted; 14763 14764 private SharedUserSetting mSharedUser; 14765 14766 public boolean isDumping(int type) { 14767 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 14768 return true; 14769 } 14770 14771 return (mTypes & type) != 0; 14772 } 14773 14774 public void setDump(int type) { 14775 mTypes |= type; 14776 } 14777 14778 public boolean isOptionEnabled(int option) { 14779 return (mOptions & option) != 0; 14780 } 14781 14782 public void setOptionEnabled(int option) { 14783 mOptions |= option; 14784 } 14785 14786 public boolean onTitlePrinted() { 14787 final boolean printed = mTitlePrinted; 14788 mTitlePrinted = true; 14789 return printed; 14790 } 14791 14792 public boolean getTitlePrinted() { 14793 return mTitlePrinted; 14794 } 14795 14796 public void setTitlePrinted(boolean enabled) { 14797 mTitlePrinted = enabled; 14798 } 14799 14800 public SharedUserSetting getSharedUser() { 14801 return mSharedUser; 14802 } 14803 14804 public void setSharedUser(SharedUserSetting user) { 14805 mSharedUser = user; 14806 } 14807 } 14808 14809 @Override 14810 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 14811 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 14812 != PackageManager.PERMISSION_GRANTED) { 14813 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 14814 + Binder.getCallingPid() 14815 + ", uid=" + Binder.getCallingUid() 14816 + " without permission " 14817 + android.Manifest.permission.DUMP); 14818 return; 14819 } 14820 14821 DumpState dumpState = new DumpState(); 14822 boolean fullPreferred = false; 14823 boolean checkin = false; 14824 14825 String packageName = null; 14826 ArraySet<String> permissionNames = null; 14827 14828 int opti = 0; 14829 while (opti < args.length) { 14830 String opt = args[opti]; 14831 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14832 break; 14833 } 14834 opti++; 14835 14836 if ("-a".equals(opt)) { 14837 // Right now we only know how to print all. 14838 } else if ("-h".equals(opt)) { 14839 pw.println("Package manager dump options:"); 14840 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 14841 pw.println(" --checkin: dump for a checkin"); 14842 pw.println(" -f: print details of intent filters"); 14843 pw.println(" -h: print this help"); 14844 pw.println(" cmd may be one of:"); 14845 pw.println(" l[ibraries]: list known shared libraries"); 14846 pw.println(" f[ibraries]: list device features"); 14847 pw.println(" k[eysets]: print known keysets"); 14848 pw.println(" r[esolvers]: dump intent resolvers"); 14849 pw.println(" perm[issions]: dump permissions"); 14850 pw.println(" permission [name ...]: dump declaration and use of given permission"); 14851 pw.println(" pref[erred]: print preferred package settings"); 14852 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 14853 pw.println(" prov[iders]: dump content providers"); 14854 pw.println(" p[ackages]: dump installed packages"); 14855 pw.println(" s[hared-users]: dump shared user IDs"); 14856 pw.println(" m[essages]: print collected runtime messages"); 14857 pw.println(" v[erifiers]: print package verifier info"); 14858 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 14859 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 14860 pw.println(" version: print database version info"); 14861 pw.println(" write: write current settings now"); 14862 pw.println(" installs: details about install sessions"); 14863 pw.println(" <package.name>: info about given package"); 14864 return; 14865 } else if ("--checkin".equals(opt)) { 14866 checkin = true; 14867 } else if ("-f".equals(opt)) { 14868 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 14869 } else { 14870 pw.println("Unknown argument: " + opt + "; use -h for help"); 14871 } 14872 } 14873 14874 // Is the caller requesting to dump a particular piece of data? 14875 if (opti < args.length) { 14876 String cmd = args[opti]; 14877 opti++; 14878 // Is this a package name? 14879 if ("android".equals(cmd) || cmd.contains(".")) { 14880 packageName = cmd; 14881 // When dumping a single package, we always dump all of its 14882 // filter information since the amount of data will be reasonable. 14883 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 14884 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 14885 dumpState.setDump(DumpState.DUMP_LIBS); 14886 } else if ("f".equals(cmd) || "features".equals(cmd)) { 14887 dumpState.setDump(DumpState.DUMP_FEATURES); 14888 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 14889 dumpState.setDump(DumpState.DUMP_RESOLVERS); 14890 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 14891 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 14892 } else if ("permission".equals(cmd)) { 14893 if (opti >= args.length) { 14894 pw.println("Error: permission requires permission name"); 14895 return; 14896 } 14897 permissionNames = new ArraySet<>(); 14898 while (opti < args.length) { 14899 permissionNames.add(args[opti]); 14900 opti++; 14901 } 14902 dumpState.setDump(DumpState.DUMP_PERMISSIONS 14903 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 14904 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 14905 dumpState.setDump(DumpState.DUMP_PREFERRED); 14906 } else if ("preferred-xml".equals(cmd)) { 14907 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 14908 if (opti < args.length && "--full".equals(args[opti])) { 14909 fullPreferred = true; 14910 opti++; 14911 } 14912 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 14913 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 14914 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 14915 dumpState.setDump(DumpState.DUMP_PACKAGES); 14916 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 14917 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 14918 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 14919 dumpState.setDump(DumpState.DUMP_PROVIDERS); 14920 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 14921 dumpState.setDump(DumpState.DUMP_MESSAGES); 14922 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 14923 dumpState.setDump(DumpState.DUMP_VERIFIERS); 14924 } else if ("i".equals(cmd) || "ifv".equals(cmd) 14925 || "intent-filter-verifiers".equals(cmd)) { 14926 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 14927 } else if ("version".equals(cmd)) { 14928 dumpState.setDump(DumpState.DUMP_VERSION); 14929 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 14930 dumpState.setDump(DumpState.DUMP_KEYSETS); 14931 } else if ("installs".equals(cmd)) { 14932 dumpState.setDump(DumpState.DUMP_INSTALLS); 14933 } else if ("write".equals(cmd)) { 14934 synchronized (mPackages) { 14935 mSettings.writeLPr(); 14936 pw.println("Settings written."); 14937 return; 14938 } 14939 } 14940 } 14941 14942 if (checkin) { 14943 pw.println("vers,1"); 14944 } 14945 14946 // reader 14947 synchronized (mPackages) { 14948 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 14949 if (!checkin) { 14950 if (dumpState.onTitlePrinted()) 14951 pw.println(); 14952 pw.println("Database versions:"); 14953 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 14954 } 14955 } 14956 14957 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 14958 if (!checkin) { 14959 if (dumpState.onTitlePrinted()) 14960 pw.println(); 14961 pw.println("Verifiers:"); 14962 pw.print(" Required: "); 14963 pw.print(mRequiredVerifierPackage); 14964 pw.print(" (uid="); 14965 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 14966 pw.println(")"); 14967 } else if (mRequiredVerifierPackage != null) { 14968 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 14969 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 14970 } 14971 } 14972 14973 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 14974 packageName == null) { 14975 if (mIntentFilterVerifierComponent != null) { 14976 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 14977 if (!checkin) { 14978 if (dumpState.onTitlePrinted()) 14979 pw.println(); 14980 pw.println("Intent Filter Verifier:"); 14981 pw.print(" Using: "); 14982 pw.print(verifierPackageName); 14983 pw.print(" (uid="); 14984 pw.print(getPackageUid(verifierPackageName, 0)); 14985 pw.println(")"); 14986 } else if (verifierPackageName != null) { 14987 pw.print("ifv,"); pw.print(verifierPackageName); 14988 pw.print(","); pw.println(getPackageUid(verifierPackageName, 0)); 14989 } 14990 } else { 14991 pw.println(); 14992 pw.println("No Intent Filter Verifier available!"); 14993 } 14994 } 14995 14996 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 14997 boolean printedHeader = false; 14998 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 14999 while (it.hasNext()) { 15000 String name = it.next(); 15001 SharedLibraryEntry ent = mSharedLibraries.get(name); 15002 if (!checkin) { 15003 if (!printedHeader) { 15004 if (dumpState.onTitlePrinted()) 15005 pw.println(); 15006 pw.println("Libraries:"); 15007 printedHeader = true; 15008 } 15009 pw.print(" "); 15010 } else { 15011 pw.print("lib,"); 15012 } 15013 pw.print(name); 15014 if (!checkin) { 15015 pw.print(" -> "); 15016 } 15017 if (ent.path != null) { 15018 if (!checkin) { 15019 pw.print("(jar) "); 15020 pw.print(ent.path); 15021 } else { 15022 pw.print(",jar,"); 15023 pw.print(ent.path); 15024 } 15025 } else { 15026 if (!checkin) { 15027 pw.print("(apk) "); 15028 pw.print(ent.apk); 15029 } else { 15030 pw.print(",apk,"); 15031 pw.print(ent.apk); 15032 } 15033 } 15034 pw.println(); 15035 } 15036 } 15037 15038 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 15039 if (dumpState.onTitlePrinted()) 15040 pw.println(); 15041 if (!checkin) { 15042 pw.println("Features:"); 15043 } 15044 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 15045 while (it.hasNext()) { 15046 String name = it.next(); 15047 if (!checkin) { 15048 pw.print(" "); 15049 } else { 15050 pw.print("feat,"); 15051 } 15052 pw.println(name); 15053 } 15054 } 15055 15056 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 15057 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 15058 : "Activity Resolver Table:", " ", packageName, 15059 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15060 dumpState.setTitlePrinted(true); 15061 } 15062 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 15063 : "Receiver Resolver Table:", " ", packageName, 15064 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15065 dumpState.setTitlePrinted(true); 15066 } 15067 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 15068 : "Service Resolver Table:", " ", packageName, 15069 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15070 dumpState.setTitlePrinted(true); 15071 } 15072 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 15073 : "Provider Resolver Table:", " ", packageName, 15074 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15075 dumpState.setTitlePrinted(true); 15076 } 15077 } 15078 15079 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 15080 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15081 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15082 int user = mSettings.mPreferredActivities.keyAt(i); 15083 if (pir.dump(pw, 15084 dumpState.getTitlePrinted() 15085 ? "\nPreferred Activities User " + user + ":" 15086 : "Preferred Activities User " + user + ":", " ", 15087 packageName, true, false)) { 15088 dumpState.setTitlePrinted(true); 15089 } 15090 } 15091 } 15092 15093 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 15094 pw.flush(); 15095 FileOutputStream fout = new FileOutputStream(fd); 15096 BufferedOutputStream str = new BufferedOutputStream(fout); 15097 XmlSerializer serializer = new FastXmlSerializer(); 15098 try { 15099 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 15100 serializer.startDocument(null, true); 15101 serializer.setFeature( 15102 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 15103 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 15104 serializer.endDocument(); 15105 serializer.flush(); 15106 } catch (IllegalArgumentException e) { 15107 pw.println("Failed writing: " + e); 15108 } catch (IllegalStateException e) { 15109 pw.println("Failed writing: " + e); 15110 } catch (IOException e) { 15111 pw.println("Failed writing: " + e); 15112 } 15113 } 15114 15115 if (!checkin 15116 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 15117 && packageName == null) { 15118 pw.println(); 15119 int count = mSettings.mPackages.size(); 15120 if (count == 0) { 15121 pw.println("No applications!"); 15122 pw.println(); 15123 } else { 15124 final String prefix = " "; 15125 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 15126 if (allPackageSettings.size() == 0) { 15127 pw.println("No domain preferred apps!"); 15128 pw.println(); 15129 } else { 15130 pw.println("App verification status:"); 15131 pw.println(); 15132 count = 0; 15133 for (PackageSetting ps : allPackageSettings) { 15134 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 15135 if (ivi == null || ivi.getPackageName() == null) continue; 15136 pw.println(prefix + "Package: " + ivi.getPackageName()); 15137 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 15138 pw.println(prefix + "Status: " + ivi.getStatusString()); 15139 pw.println(); 15140 count++; 15141 } 15142 if (count == 0) { 15143 pw.println(prefix + "No app verification established."); 15144 pw.println(); 15145 } 15146 for (int userId : sUserManager.getUserIds()) { 15147 pw.println("App linkages for user " + userId + ":"); 15148 pw.println(); 15149 count = 0; 15150 for (PackageSetting ps : allPackageSettings) { 15151 final long status = ps.getDomainVerificationStatusForUser(userId); 15152 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 15153 continue; 15154 } 15155 pw.println(prefix + "Package: " + ps.name); 15156 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 15157 String statusStr = IntentFilterVerificationInfo. 15158 getStatusStringFromValue(status); 15159 pw.println(prefix + "Status: " + statusStr); 15160 pw.println(); 15161 count++; 15162 } 15163 if (count == 0) { 15164 pw.println(prefix + "No configured app linkages."); 15165 pw.println(); 15166 } 15167 } 15168 } 15169 } 15170 } 15171 15172 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 15173 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 15174 if (packageName == null && permissionNames == null) { 15175 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 15176 if (iperm == 0) { 15177 if (dumpState.onTitlePrinted()) 15178 pw.println(); 15179 pw.println("AppOp Permissions:"); 15180 } 15181 pw.print(" AppOp Permission "); 15182 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 15183 pw.println(":"); 15184 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 15185 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 15186 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 15187 } 15188 } 15189 } 15190 } 15191 15192 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 15193 boolean printedSomething = false; 15194 for (PackageParser.Provider p : mProviders.mProviders.values()) { 15195 if (packageName != null && !packageName.equals(p.info.packageName)) { 15196 continue; 15197 } 15198 if (!printedSomething) { 15199 if (dumpState.onTitlePrinted()) 15200 pw.println(); 15201 pw.println("Registered ContentProviders:"); 15202 printedSomething = true; 15203 } 15204 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 15205 pw.print(" "); pw.println(p.toString()); 15206 } 15207 printedSomething = false; 15208 for (Map.Entry<String, PackageParser.Provider> entry : 15209 mProvidersByAuthority.entrySet()) { 15210 PackageParser.Provider p = entry.getValue(); 15211 if (packageName != null && !packageName.equals(p.info.packageName)) { 15212 continue; 15213 } 15214 if (!printedSomething) { 15215 if (dumpState.onTitlePrinted()) 15216 pw.println(); 15217 pw.println("ContentProvider Authorities:"); 15218 printedSomething = true; 15219 } 15220 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 15221 pw.print(" "); pw.println(p.toString()); 15222 if (p.info != null && p.info.applicationInfo != null) { 15223 final String appInfo = p.info.applicationInfo.toString(); 15224 pw.print(" applicationInfo="); pw.println(appInfo); 15225 } 15226 } 15227 } 15228 15229 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 15230 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 15231 } 15232 15233 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 15234 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 15235 } 15236 15237 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 15238 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 15239 } 15240 15241 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 15242 // XXX should handle packageName != null by dumping only install data that 15243 // the given package is involved with. 15244 if (dumpState.onTitlePrinted()) pw.println(); 15245 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 15246 } 15247 15248 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 15249 if (dumpState.onTitlePrinted()) pw.println(); 15250 mSettings.dumpReadMessagesLPr(pw, dumpState); 15251 15252 pw.println(); 15253 pw.println("Package warning messages:"); 15254 BufferedReader in = null; 15255 String line = null; 15256 try { 15257 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 15258 while ((line = in.readLine()) != null) { 15259 if (line.contains("ignored: updated version")) continue; 15260 pw.println(line); 15261 } 15262 } catch (IOException ignored) { 15263 } finally { 15264 IoUtils.closeQuietly(in); 15265 } 15266 } 15267 15268 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 15269 BufferedReader in = null; 15270 String line = null; 15271 try { 15272 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 15273 while ((line = in.readLine()) != null) { 15274 if (line.contains("ignored: updated version")) continue; 15275 pw.print("msg,"); 15276 pw.println(line); 15277 } 15278 } catch (IOException ignored) { 15279 } finally { 15280 IoUtils.closeQuietly(in); 15281 } 15282 } 15283 } 15284 } 15285 15286 private String dumpDomainString(String packageName) { 15287 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName); 15288 List<IntentFilter> filters = getAllIntentFilters(packageName); 15289 15290 ArraySet<String> result = new ArraySet<>(); 15291 if (iviList.size() > 0) { 15292 for (IntentFilterVerificationInfo ivi : iviList) { 15293 for (String host : ivi.getDomains()) { 15294 result.add(host); 15295 } 15296 } 15297 } 15298 if (filters != null && filters.size() > 0) { 15299 for (IntentFilter filter : filters) { 15300 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 15301 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 15302 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 15303 result.addAll(filter.getHostsList()); 15304 } 15305 } 15306 } 15307 15308 StringBuilder sb = new StringBuilder(result.size() * 16); 15309 for (String domain : result) { 15310 if (sb.length() > 0) sb.append(" "); 15311 sb.append(domain); 15312 } 15313 return sb.toString(); 15314 } 15315 15316 // ------- apps on sdcard specific code ------- 15317 static final boolean DEBUG_SD_INSTALL = false; 15318 15319 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 15320 15321 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 15322 15323 private boolean mMediaMounted = false; 15324 15325 static String getEncryptKey() { 15326 try { 15327 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 15328 SD_ENCRYPTION_KEYSTORE_NAME); 15329 if (sdEncKey == null) { 15330 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 15331 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 15332 if (sdEncKey == null) { 15333 Slog.e(TAG, "Failed to create encryption keys"); 15334 return null; 15335 } 15336 } 15337 return sdEncKey; 15338 } catch (NoSuchAlgorithmException nsae) { 15339 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 15340 return null; 15341 } catch (IOException ioe) { 15342 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 15343 return null; 15344 } 15345 } 15346 15347 /* 15348 * Update media status on PackageManager. 15349 */ 15350 @Override 15351 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 15352 int callingUid = Binder.getCallingUid(); 15353 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15354 throw new SecurityException("Media status can only be updated by the system"); 15355 } 15356 // reader; this apparently protects mMediaMounted, but should probably 15357 // be a different lock in that case. 15358 synchronized (mPackages) { 15359 Log.i(TAG, "Updating external media status from " 15360 + (mMediaMounted ? "mounted" : "unmounted") + " to " 15361 + (mediaStatus ? "mounted" : "unmounted")); 15362 if (DEBUG_SD_INSTALL) 15363 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 15364 + ", mMediaMounted=" + mMediaMounted); 15365 if (mediaStatus == mMediaMounted) { 15366 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 15367 : 0, -1); 15368 mHandler.sendMessage(msg); 15369 return; 15370 } 15371 mMediaMounted = mediaStatus; 15372 } 15373 // Queue up an async operation since the package installation may take a 15374 // little while. 15375 mHandler.post(new Runnable() { 15376 public void run() { 15377 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 15378 } 15379 }); 15380 } 15381 15382 /** 15383 * Called by MountService when the initial ASECs to scan are available. 15384 * Should block until all the ASEC containers are finished being scanned. 15385 */ 15386 public void scanAvailableAsecs() { 15387 updateExternalMediaStatusInner(true, false, false); 15388 if (mShouldRestoreconData) { 15389 SELinuxMMAC.setRestoreconDone(); 15390 mShouldRestoreconData = false; 15391 } 15392 } 15393 15394 /* 15395 * Collect information of applications on external media, map them against 15396 * existing containers and update information based on current mount status. 15397 * Please note that we always have to report status if reportStatus has been 15398 * set to true especially when unloading packages. 15399 */ 15400 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 15401 boolean externalStorage) { 15402 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 15403 int[] uidArr = EmptyArray.INT; 15404 15405 final String[] list = PackageHelper.getSecureContainerList(); 15406 if (ArrayUtils.isEmpty(list)) { 15407 Log.i(TAG, "No secure containers found"); 15408 } else { 15409 // Process list of secure containers and categorize them 15410 // as active or stale based on their package internal state. 15411 15412 // reader 15413 synchronized (mPackages) { 15414 for (String cid : list) { 15415 // Leave stages untouched for now; installer service owns them 15416 if (PackageInstallerService.isStageName(cid)) continue; 15417 15418 if (DEBUG_SD_INSTALL) 15419 Log.i(TAG, "Processing container " + cid); 15420 String pkgName = getAsecPackageName(cid); 15421 if (pkgName == null) { 15422 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 15423 continue; 15424 } 15425 if (DEBUG_SD_INSTALL) 15426 Log.i(TAG, "Looking for pkg : " + pkgName); 15427 15428 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15429 if (ps == null) { 15430 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 15431 continue; 15432 } 15433 15434 /* 15435 * Skip packages that are not external if we're unmounting 15436 * external storage. 15437 */ 15438 if (externalStorage && !isMounted && !isExternal(ps)) { 15439 continue; 15440 } 15441 15442 final AsecInstallArgs args = new AsecInstallArgs(cid, 15443 getAppDexInstructionSets(ps), ps.isForwardLocked()); 15444 // The package status is changed only if the code path 15445 // matches between settings and the container id. 15446 if (ps.codePathString != null 15447 && ps.codePathString.startsWith(args.getCodePath())) { 15448 if (DEBUG_SD_INSTALL) { 15449 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 15450 + " at code path: " + ps.codePathString); 15451 } 15452 15453 // We do have a valid package installed on sdcard 15454 processCids.put(args, ps.codePathString); 15455 final int uid = ps.appId; 15456 if (uid != -1) { 15457 uidArr = ArrayUtils.appendInt(uidArr, uid); 15458 } 15459 } else { 15460 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 15461 + ps.codePathString); 15462 } 15463 } 15464 } 15465 15466 Arrays.sort(uidArr); 15467 } 15468 15469 // Process packages with valid entries. 15470 if (isMounted) { 15471 if (DEBUG_SD_INSTALL) 15472 Log.i(TAG, "Loading packages"); 15473 loadMediaPackages(processCids, uidArr); 15474 startCleaningPackages(); 15475 mInstallerService.onSecureContainersAvailable(); 15476 } else { 15477 if (DEBUG_SD_INSTALL) 15478 Log.i(TAG, "Unloading packages"); 15479 unloadMediaPackages(processCids, uidArr, reportStatus); 15480 } 15481 } 15482 15483 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15484 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 15485 final int size = infos.size(); 15486 final String[] packageNames = new String[size]; 15487 final int[] packageUids = new int[size]; 15488 for (int i = 0; i < size; i++) { 15489 final ApplicationInfo info = infos.get(i); 15490 packageNames[i] = info.packageName; 15491 packageUids[i] = info.uid; 15492 } 15493 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 15494 finishedReceiver); 15495 } 15496 15497 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15498 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 15499 sendResourcesChangedBroadcast(mediaStatus, replacing, 15500 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 15501 } 15502 15503 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15504 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 15505 int size = pkgList.length; 15506 if (size > 0) { 15507 // Send broadcasts here 15508 Bundle extras = new Bundle(); 15509 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 15510 if (uidArr != null) { 15511 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 15512 } 15513 if (replacing) { 15514 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 15515 } 15516 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 15517 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 15518 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 15519 } 15520 } 15521 15522 /* 15523 * Look at potentially valid container ids from processCids If package 15524 * information doesn't match the one on record or package scanning fails, 15525 * the cid is added to list of removeCids. We currently don't delete stale 15526 * containers. 15527 */ 15528 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) { 15529 ArrayList<String> pkgList = new ArrayList<String>(); 15530 Set<AsecInstallArgs> keys = processCids.keySet(); 15531 15532 for (AsecInstallArgs args : keys) { 15533 String codePath = processCids.get(args); 15534 if (DEBUG_SD_INSTALL) 15535 Log.i(TAG, "Loading container : " + args.cid); 15536 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15537 try { 15538 // Make sure there are no container errors first. 15539 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 15540 Slog.e(TAG, "Failed to mount cid : " + args.cid 15541 + " when installing from sdcard"); 15542 continue; 15543 } 15544 // Check code path here. 15545 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 15546 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 15547 + " does not match one in settings " + codePath); 15548 continue; 15549 } 15550 // Parse package 15551 int parseFlags = mDefParseFlags; 15552 if (args.isExternalAsec()) { 15553 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 15554 } 15555 if (args.isFwdLocked()) { 15556 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 15557 } 15558 15559 synchronized (mInstallLock) { 15560 PackageParser.Package pkg = null; 15561 try { 15562 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 15563 } catch (PackageManagerException e) { 15564 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 15565 } 15566 // Scan the package 15567 if (pkg != null) { 15568 /* 15569 * TODO why is the lock being held? doPostInstall is 15570 * called in other places without the lock. This needs 15571 * to be straightened out. 15572 */ 15573 // writer 15574 synchronized (mPackages) { 15575 retCode = PackageManager.INSTALL_SUCCEEDED; 15576 pkgList.add(pkg.packageName); 15577 // Post process args 15578 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 15579 pkg.applicationInfo.uid); 15580 } 15581 } else { 15582 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 15583 } 15584 } 15585 15586 } finally { 15587 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 15588 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 15589 } 15590 } 15591 } 15592 // writer 15593 synchronized (mPackages) { 15594 // If the platform SDK has changed since the last time we booted, 15595 // we need to re-grant app permission to catch any new ones that 15596 // appear. This is really a hack, and means that apps can in some 15597 // cases get permissions that the user didn't initially explicitly 15598 // allow... it would be nice to have some better way to handle 15599 // this situation. 15600 final VersionInfo ver = mSettings.getExternalVersion(); 15601 15602 int updateFlags = UPDATE_PERMISSIONS_ALL; 15603 if (ver.sdkVersion != mSdkVersion) { 15604 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 15605 + mSdkVersion + "; regranting permissions for external"); 15606 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 15607 } 15608 updatePermissionsLPw(null, null, updateFlags); 15609 15610 // Yay, everything is now upgraded 15611 ver.forceCurrent(); 15612 15613 // can downgrade to reader 15614 // Persist settings 15615 mSettings.writeLPr(); 15616 } 15617 // Send a broadcast to let everyone know we are done processing 15618 if (pkgList.size() > 0) { 15619 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 15620 } 15621 } 15622 15623 /* 15624 * Utility method to unload a list of specified containers 15625 */ 15626 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 15627 // Just unmount all valid containers. 15628 for (AsecInstallArgs arg : cidArgs) { 15629 synchronized (mInstallLock) { 15630 arg.doPostDeleteLI(false); 15631 } 15632 } 15633 } 15634 15635 /* 15636 * Unload packages mounted on external media. This involves deleting package 15637 * data from internal structures, sending broadcasts about diabled packages, 15638 * gc'ing to free up references, unmounting all secure containers 15639 * corresponding to packages on external media, and posting a 15640 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 15641 * that we always have to post this message if status has been requested no 15642 * matter what. 15643 */ 15644 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 15645 final boolean reportStatus) { 15646 if (DEBUG_SD_INSTALL) 15647 Log.i(TAG, "unloading media packages"); 15648 ArrayList<String> pkgList = new ArrayList<String>(); 15649 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 15650 final Set<AsecInstallArgs> keys = processCids.keySet(); 15651 for (AsecInstallArgs args : keys) { 15652 String pkgName = args.getPackageName(); 15653 if (DEBUG_SD_INSTALL) 15654 Log.i(TAG, "Trying to unload pkg : " + pkgName); 15655 // Delete package internally 15656 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 15657 synchronized (mInstallLock) { 15658 boolean res = deletePackageLI(pkgName, null, false, null, null, 15659 PackageManager.DELETE_KEEP_DATA, outInfo, false); 15660 if (res) { 15661 pkgList.add(pkgName); 15662 } else { 15663 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 15664 failedList.add(args); 15665 } 15666 } 15667 } 15668 15669 // reader 15670 synchronized (mPackages) { 15671 // We didn't update the settings after removing each package; 15672 // write them now for all packages. 15673 mSettings.writeLPr(); 15674 } 15675 15676 // We have to absolutely send UPDATED_MEDIA_STATUS only 15677 // after confirming that all the receivers processed the ordered 15678 // broadcast when packages get disabled, force a gc to clean things up. 15679 // and unload all the containers. 15680 if (pkgList.size() > 0) { 15681 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 15682 new IIntentReceiver.Stub() { 15683 public void performReceive(Intent intent, int resultCode, String data, 15684 Bundle extras, boolean ordered, boolean sticky, 15685 int sendingUser) throws RemoteException { 15686 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 15687 reportStatus ? 1 : 0, 1, keys); 15688 mHandler.sendMessage(msg); 15689 } 15690 }); 15691 } else { 15692 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 15693 keys); 15694 mHandler.sendMessage(msg); 15695 } 15696 } 15697 15698 private void loadPrivatePackages(VolumeInfo vol) { 15699 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 15700 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 15701 synchronized (mInstallLock) { 15702 synchronized (mPackages) { 15703 final VersionInfo ver = mSettings.findOrCreateVersion(vol.fsUuid); 15704 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 15705 for (PackageSetting ps : packages) { 15706 final PackageParser.Package pkg; 15707 try { 15708 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null); 15709 loaded.add(pkg.applicationInfo); 15710 } catch (PackageManagerException e) { 15711 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 15712 } 15713 15714 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 15715 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 15716 } 15717 } 15718 15719 int updateFlags = UPDATE_PERMISSIONS_ALL; 15720 if (ver.sdkVersion != mSdkVersion) { 15721 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 15722 + mSdkVersion + "; regranting permissions for " + vol.fsUuid); 15723 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 15724 } 15725 updatePermissionsLPw(null, null, updateFlags); 15726 15727 // Yay, everything is now upgraded 15728 ver.forceCurrent(); 15729 15730 mSettings.writeLPr(); 15731 } 15732 } 15733 15734 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 15735 sendResourcesChangedBroadcast(true, false, loaded, null); 15736 } 15737 15738 private void unloadPrivatePackages(VolumeInfo vol) { 15739 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 15740 synchronized (mInstallLock) { 15741 synchronized (mPackages) { 15742 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 15743 for (PackageSetting ps : packages) { 15744 if (ps.pkg == null) continue; 15745 15746 final ApplicationInfo info = ps.pkg.applicationInfo; 15747 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 15748 if (deletePackageLI(ps.name, null, false, null, null, 15749 PackageManager.DELETE_KEEP_DATA, outInfo, false)) { 15750 unloaded.add(info); 15751 } else { 15752 Slog.w(TAG, "Failed to unload " + ps.codePath); 15753 } 15754 } 15755 15756 mSettings.writeLPr(); 15757 } 15758 } 15759 15760 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 15761 sendResourcesChangedBroadcast(false, false, unloaded, null); 15762 } 15763 15764 /** 15765 * Examine all users present on given mounted volume, and destroy data 15766 * belonging to users that are no longer valid, or whose user ID has been 15767 * recycled. 15768 */ 15769 private void reconcileUsers(String volumeUuid) { 15770 final File[] files = FileUtils 15771 .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid)); 15772 for (File file : files) { 15773 if (!file.isDirectory()) continue; 15774 15775 final int userId; 15776 final UserInfo info; 15777 try { 15778 userId = Integer.parseInt(file.getName()); 15779 info = sUserManager.getUserInfo(userId); 15780 } catch (NumberFormatException e) { 15781 Slog.w(TAG, "Invalid user directory " + file); 15782 continue; 15783 } 15784 15785 boolean destroyUser = false; 15786 if (info == null) { 15787 logCriticalInfo(Log.WARN, "Destroying user directory " + file 15788 + " because no matching user was found"); 15789 destroyUser = true; 15790 } else { 15791 try { 15792 UserManagerService.enforceSerialNumber(file, info.serialNumber); 15793 } catch (IOException e) { 15794 logCriticalInfo(Log.WARN, "Destroying user directory " + file 15795 + " because we failed to enforce serial number: " + e); 15796 destroyUser = true; 15797 } 15798 } 15799 15800 if (destroyUser) { 15801 synchronized (mInstallLock) { 15802 mInstaller.removeUserDataDirs(volumeUuid, userId); 15803 } 15804 } 15805 } 15806 15807 final UserManager um = mContext.getSystemService(UserManager.class); 15808 for (UserInfo user : um.getUsers()) { 15809 final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id); 15810 if (userDir.exists()) continue; 15811 15812 try { 15813 UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id); 15814 UserManagerService.enforceSerialNumber(userDir, user.serialNumber); 15815 } catch (IOException e) { 15816 Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e); 15817 } 15818 } 15819 } 15820 15821 /** 15822 * Examine all apps present on given mounted volume, and destroy apps that 15823 * aren't expected, either due to uninstallation or reinstallation on 15824 * another volume. 15825 */ 15826 private void reconcileApps(String volumeUuid) { 15827 final File[] files = FileUtils 15828 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 15829 for (File file : files) { 15830 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 15831 && !PackageInstallerService.isStageName(file.getName()); 15832 if (!isPackage) { 15833 // Ignore entries which are not packages 15834 continue; 15835 } 15836 15837 boolean destroyApp = false; 15838 String packageName = null; 15839 try { 15840 final PackageLite pkg = PackageParser.parsePackageLite(file, 15841 PackageParser.PARSE_MUST_BE_APK); 15842 packageName = pkg.packageName; 15843 15844 synchronized (mPackages) { 15845 final PackageSetting ps = mSettings.mPackages.get(packageName); 15846 if (ps == null) { 15847 logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + " 15848 + volumeUuid + " because we found no install record"); 15849 destroyApp = true; 15850 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 15851 logCriticalInfo(Log.WARN, "Destroying " + packageName + " on " 15852 + volumeUuid + " because we expected it on " + ps.volumeUuid); 15853 destroyApp = true; 15854 } 15855 } 15856 15857 } catch (PackageParserException e) { 15858 logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e); 15859 destroyApp = true; 15860 } 15861 15862 if (destroyApp) { 15863 synchronized (mInstallLock) { 15864 if (packageName != null) { 15865 removeDataDirsLI(volumeUuid, packageName); 15866 } 15867 if (file.isDirectory()) { 15868 mInstaller.rmPackageDir(file.getAbsolutePath()); 15869 } else { 15870 file.delete(); 15871 } 15872 } 15873 } 15874 } 15875 } 15876 15877 private void unfreezePackage(String packageName) { 15878 synchronized (mPackages) { 15879 final PackageSetting ps = mSettings.mPackages.get(packageName); 15880 if (ps != null) { 15881 ps.frozen = false; 15882 } 15883 } 15884 } 15885 15886 @Override 15887 public int movePackage(final String packageName, final String volumeUuid) { 15888 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 15889 15890 final int moveId = mNextMoveId.getAndIncrement(); 15891 try { 15892 movePackageInternal(packageName, volumeUuid, moveId); 15893 } catch (PackageManagerException e) { 15894 Slog.w(TAG, "Failed to move " + packageName, e); 15895 mMoveCallbacks.notifyStatusChanged(moveId, 15896 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 15897 } 15898 return moveId; 15899 } 15900 15901 private void movePackageInternal(final String packageName, final String volumeUuid, 15902 final int moveId) throws PackageManagerException { 15903 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 15904 final StorageManager storage = mContext.getSystemService(StorageManager.class); 15905 final PackageManager pm = mContext.getPackageManager(); 15906 15907 final boolean currentAsec; 15908 final String currentVolumeUuid; 15909 final File codeFile; 15910 final String installerPackageName; 15911 final String packageAbiOverride; 15912 final int appId; 15913 final String seinfo; 15914 final String label; 15915 15916 // reader 15917 synchronized (mPackages) { 15918 final PackageParser.Package pkg = mPackages.get(packageName); 15919 final PackageSetting ps = mSettings.mPackages.get(packageName); 15920 if (pkg == null || ps == null) { 15921 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 15922 } 15923 15924 if (pkg.applicationInfo.isSystemApp()) { 15925 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 15926 "Cannot move system application"); 15927 } 15928 15929 if (Objects.equals(ps.volumeUuid, volumeUuid)) { 15930 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 15931 "Package already moved to " + volumeUuid); 15932 } 15933 15934 final File probe = new File(pkg.codePath); 15935 final File probeOat = new File(probe, "oat"); 15936 if (!probe.isDirectory() || !probeOat.isDirectory()) { 15937 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 15938 "Move only supported for modern cluster style installs"); 15939 } 15940 15941 if (ps.frozen) { 15942 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 15943 "Failed to move already frozen package"); 15944 } 15945 ps.frozen = true; 15946 15947 currentAsec = pkg.applicationInfo.isForwardLocked() 15948 || pkg.applicationInfo.isExternalAsec(); 15949 currentVolumeUuid = ps.volumeUuid; 15950 codeFile = new File(pkg.codePath); 15951 installerPackageName = ps.installerPackageName; 15952 packageAbiOverride = ps.cpuAbiOverrideString; 15953 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 15954 seinfo = pkg.applicationInfo.seinfo; 15955 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 15956 } 15957 15958 // Now that we're guarded by frozen state, kill app during move 15959 final long token = Binder.clearCallingIdentity(); 15960 try { 15961 killApplication(packageName, appId, "move pkg"); 15962 } finally { 15963 Binder.restoreCallingIdentity(token); 15964 } 15965 15966 final Bundle extras = new Bundle(); 15967 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 15968 extras.putString(Intent.EXTRA_TITLE, label); 15969 mMoveCallbacks.notifyCreated(moveId, extras); 15970 15971 int installFlags; 15972 final boolean moveCompleteApp; 15973 final File measurePath; 15974 15975 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 15976 installFlags = INSTALL_INTERNAL; 15977 moveCompleteApp = !currentAsec; 15978 measurePath = Environment.getDataAppDirectory(volumeUuid); 15979 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 15980 installFlags = INSTALL_EXTERNAL; 15981 moveCompleteApp = false; 15982 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 15983 } else { 15984 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 15985 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 15986 || !volume.isMountedWritable()) { 15987 unfreezePackage(packageName); 15988 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 15989 "Move location not mounted private volume"); 15990 } 15991 15992 Preconditions.checkState(!currentAsec); 15993 15994 installFlags = INSTALL_INTERNAL; 15995 moveCompleteApp = true; 15996 measurePath = Environment.getDataAppDirectory(volumeUuid); 15997 } 15998 15999 final PackageStats stats = new PackageStats(null, -1); 16000 synchronized (mInstaller) { 16001 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 16002 unfreezePackage(packageName); 16003 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16004 "Failed to measure package size"); 16005 } 16006 } 16007 16008 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 16009 + stats.dataSize); 16010 16011 final long startFreeBytes = measurePath.getFreeSpace(); 16012 final long sizeBytes; 16013 if (moveCompleteApp) { 16014 sizeBytes = stats.codeSize + stats.dataSize; 16015 } else { 16016 sizeBytes = stats.codeSize; 16017 } 16018 16019 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 16020 unfreezePackage(packageName); 16021 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16022 "Not enough free space to move"); 16023 } 16024 16025 mMoveCallbacks.notifyStatusChanged(moveId, 10); 16026 16027 final CountDownLatch installedLatch = new CountDownLatch(1); 16028 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 16029 @Override 16030 public void onUserActionRequired(Intent intent) throws RemoteException { 16031 throw new IllegalStateException(); 16032 } 16033 16034 @Override 16035 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 16036 Bundle extras) throws RemoteException { 16037 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 16038 + PackageManager.installStatusToString(returnCode, msg)); 16039 16040 installedLatch.countDown(); 16041 16042 // Regardless of success or failure of the move operation, 16043 // always unfreeze the package 16044 unfreezePackage(packageName); 16045 16046 final int status = PackageManager.installStatusToPublicStatus(returnCode); 16047 switch (status) { 16048 case PackageInstaller.STATUS_SUCCESS: 16049 mMoveCallbacks.notifyStatusChanged(moveId, 16050 PackageManager.MOVE_SUCCEEDED); 16051 break; 16052 case PackageInstaller.STATUS_FAILURE_STORAGE: 16053 mMoveCallbacks.notifyStatusChanged(moveId, 16054 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 16055 break; 16056 default: 16057 mMoveCallbacks.notifyStatusChanged(moveId, 16058 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 16059 break; 16060 } 16061 } 16062 }; 16063 16064 final MoveInfo move; 16065 if (moveCompleteApp) { 16066 // Kick off a thread to report progress estimates 16067 new Thread() { 16068 @Override 16069 public void run() { 16070 while (true) { 16071 try { 16072 if (installedLatch.await(1, TimeUnit.SECONDS)) { 16073 break; 16074 } 16075 } catch (InterruptedException ignored) { 16076 } 16077 16078 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 16079 final int progress = 10 + (int) MathUtils.constrain( 16080 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 16081 mMoveCallbacks.notifyStatusChanged(moveId, progress); 16082 } 16083 } 16084 }.start(); 16085 16086 final String dataAppName = codeFile.getName(); 16087 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 16088 dataAppName, appId, seinfo); 16089 } else { 16090 move = null; 16091 } 16092 16093 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 16094 16095 final Message msg = mHandler.obtainMessage(INIT_COPY); 16096 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 16097 msg.obj = new InstallParams(origin, move, installObserver, installFlags, 16098 installerPackageName, volumeUuid, null, user, packageAbiOverride, null); 16099 mHandler.sendMessage(msg); 16100 } 16101 16102 @Override 16103 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 16104 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 16105 16106 final int realMoveId = mNextMoveId.getAndIncrement(); 16107 final Bundle extras = new Bundle(); 16108 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 16109 mMoveCallbacks.notifyCreated(realMoveId, extras); 16110 16111 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 16112 @Override 16113 public void onCreated(int moveId, Bundle extras) { 16114 // Ignored 16115 } 16116 16117 @Override 16118 public void onStatusChanged(int moveId, int status, long estMillis) { 16119 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 16120 } 16121 }; 16122 16123 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16124 storage.setPrimaryStorageUuid(volumeUuid, callback); 16125 return realMoveId; 16126 } 16127 16128 @Override 16129 public int getMoveStatus(int moveId) { 16130 mContext.enforceCallingOrSelfPermission( 16131 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16132 return mMoveCallbacks.mLastStatus.get(moveId); 16133 } 16134 16135 @Override 16136 public void registerMoveCallback(IPackageMoveObserver callback) { 16137 mContext.enforceCallingOrSelfPermission( 16138 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16139 mMoveCallbacks.register(callback); 16140 } 16141 16142 @Override 16143 public void unregisterMoveCallback(IPackageMoveObserver callback) { 16144 mContext.enforceCallingOrSelfPermission( 16145 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16146 mMoveCallbacks.unregister(callback); 16147 } 16148 16149 @Override 16150 public boolean setInstallLocation(int loc) { 16151 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 16152 null); 16153 if (getInstallLocation() == loc) { 16154 return true; 16155 } 16156 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 16157 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 16158 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 16159 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 16160 return true; 16161 } 16162 return false; 16163 } 16164 16165 @Override 16166 public int getInstallLocation() { 16167 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 16168 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 16169 PackageHelper.APP_INSTALL_AUTO); 16170 } 16171 16172 /** Called by UserManagerService */ 16173 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 16174 mDirtyUsers.remove(userHandle); 16175 mSettings.removeUserLPw(userHandle); 16176 mPendingBroadcasts.remove(userHandle); 16177 if (mInstaller != null) { 16178 // Technically, we shouldn't be doing this with the package lock 16179 // held. However, this is very rare, and there is already so much 16180 // other disk I/O going on, that we'll let it slide for now. 16181 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16182 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 16183 final String volumeUuid = vol.getFsUuid(); 16184 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 16185 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 16186 } 16187 } 16188 mUserNeedsBadging.delete(userHandle); 16189 removeUnusedPackagesLILPw(userManager, userHandle); 16190 } 16191 16192 /** 16193 * We're removing userHandle and would like to remove any downloaded packages 16194 * that are no longer in use by any other user. 16195 * @param userHandle the user being removed 16196 */ 16197 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 16198 final boolean DEBUG_CLEAN_APKS = false; 16199 int [] users = userManager.getUserIdsLPr(); 16200 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 16201 while (psit.hasNext()) { 16202 PackageSetting ps = psit.next(); 16203 if (ps.pkg == null) { 16204 continue; 16205 } 16206 final String packageName = ps.pkg.packageName; 16207 // Skip over if system app 16208 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 16209 continue; 16210 } 16211 if (DEBUG_CLEAN_APKS) { 16212 Slog.i(TAG, "Checking package " + packageName); 16213 } 16214 boolean keep = false; 16215 for (int i = 0; i < users.length; i++) { 16216 if (users[i] != userHandle && ps.getInstalled(users[i])) { 16217 keep = true; 16218 if (DEBUG_CLEAN_APKS) { 16219 Slog.i(TAG, " Keeping package " + packageName + " for user " 16220 + users[i]); 16221 } 16222 break; 16223 } 16224 } 16225 if (!keep) { 16226 if (DEBUG_CLEAN_APKS) { 16227 Slog.i(TAG, " Removing package " + packageName); 16228 } 16229 mHandler.post(new Runnable() { 16230 public void run() { 16231 deletePackageX(packageName, userHandle, 0); 16232 } //end run 16233 }); 16234 } 16235 } 16236 } 16237 16238 /** Called by UserManagerService */ 16239 void createNewUserLILPw(int userHandle) { 16240 if (mInstaller != null) { 16241 mInstaller.createUserConfig(userHandle); 16242 mSettings.createNewUserLILPw(this, mInstaller, userHandle); 16243 applyFactoryDefaultBrowserLPw(userHandle); 16244 primeDomainVerificationsLPw(userHandle); 16245 } 16246 } 16247 16248 void newUserCreated(final int userHandle) { 16249 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 16250 } 16251 16252 @Override 16253 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 16254 mContext.enforceCallingOrSelfPermission( 16255 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 16256 "Only package verification agents can read the verifier device identity"); 16257 16258 synchronized (mPackages) { 16259 return mSettings.getVerifierDeviceIdentityLPw(); 16260 } 16261 } 16262 16263 @Override 16264 public void setPermissionEnforced(String permission, boolean enforced) { 16265 // TODO: Now that we no longer change GID for storage, this should to away. 16266 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 16267 "setPermissionEnforced"); 16268 if (READ_EXTERNAL_STORAGE.equals(permission)) { 16269 synchronized (mPackages) { 16270 if (mSettings.mReadExternalStorageEnforced == null 16271 || mSettings.mReadExternalStorageEnforced != enforced) { 16272 mSettings.mReadExternalStorageEnforced = enforced; 16273 mSettings.writeLPr(); 16274 } 16275 } 16276 // kill any non-foreground processes so we restart them and 16277 // grant/revoke the GID. 16278 final IActivityManager am = ActivityManagerNative.getDefault(); 16279 if (am != null) { 16280 final long token = Binder.clearCallingIdentity(); 16281 try { 16282 am.killProcessesBelowForeground("setPermissionEnforcement"); 16283 } catch (RemoteException e) { 16284 } finally { 16285 Binder.restoreCallingIdentity(token); 16286 } 16287 } 16288 } else { 16289 throw new IllegalArgumentException("No selective enforcement for " + permission); 16290 } 16291 } 16292 16293 @Override 16294 @Deprecated 16295 public boolean isPermissionEnforced(String permission) { 16296 return true; 16297 } 16298 16299 @Override 16300 public boolean isStorageLow() { 16301 final long token = Binder.clearCallingIdentity(); 16302 try { 16303 final DeviceStorageMonitorInternal 16304 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 16305 if (dsm != null) { 16306 return dsm.isMemoryLow(); 16307 } else { 16308 return false; 16309 } 16310 } finally { 16311 Binder.restoreCallingIdentity(token); 16312 } 16313 } 16314 16315 @Override 16316 public IPackageInstaller getPackageInstaller() { 16317 return mInstallerService; 16318 } 16319 16320 private boolean userNeedsBadging(int userId) { 16321 int index = mUserNeedsBadging.indexOfKey(userId); 16322 if (index < 0) { 16323 final UserInfo userInfo; 16324 final long token = Binder.clearCallingIdentity(); 16325 try { 16326 userInfo = sUserManager.getUserInfo(userId); 16327 } finally { 16328 Binder.restoreCallingIdentity(token); 16329 } 16330 final boolean b; 16331 if (userInfo != null && userInfo.isManagedProfile()) { 16332 b = true; 16333 } else { 16334 b = false; 16335 } 16336 mUserNeedsBadging.put(userId, b); 16337 return b; 16338 } 16339 return mUserNeedsBadging.valueAt(index); 16340 } 16341 16342 @Override 16343 public KeySet getKeySetByAlias(String packageName, String alias) { 16344 if (packageName == null || alias == null) { 16345 return null; 16346 } 16347 synchronized(mPackages) { 16348 final PackageParser.Package pkg = mPackages.get(packageName); 16349 if (pkg == null) { 16350 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16351 throw new IllegalArgumentException("Unknown package: " + packageName); 16352 } 16353 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16354 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 16355 } 16356 } 16357 16358 @Override 16359 public KeySet getSigningKeySet(String packageName) { 16360 if (packageName == null) { 16361 return null; 16362 } 16363 synchronized(mPackages) { 16364 final PackageParser.Package pkg = mPackages.get(packageName); 16365 if (pkg == null) { 16366 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16367 throw new IllegalArgumentException("Unknown package: " + packageName); 16368 } 16369 if (pkg.applicationInfo.uid != Binder.getCallingUid() 16370 && Process.SYSTEM_UID != Binder.getCallingUid()) { 16371 throw new SecurityException("May not access signing KeySet of other apps."); 16372 } 16373 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16374 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 16375 } 16376 } 16377 16378 @Override 16379 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 16380 if (packageName == null || ks == null) { 16381 return false; 16382 } 16383 synchronized(mPackages) { 16384 final PackageParser.Package pkg = mPackages.get(packageName); 16385 if (pkg == null) { 16386 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16387 throw new IllegalArgumentException("Unknown package: " + packageName); 16388 } 16389 IBinder ksh = ks.getToken(); 16390 if (ksh instanceof KeySetHandle) { 16391 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16392 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 16393 } 16394 return false; 16395 } 16396 } 16397 16398 @Override 16399 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 16400 if (packageName == null || ks == null) { 16401 return false; 16402 } 16403 synchronized(mPackages) { 16404 final PackageParser.Package pkg = mPackages.get(packageName); 16405 if (pkg == null) { 16406 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16407 throw new IllegalArgumentException("Unknown package: " + packageName); 16408 } 16409 IBinder ksh = ks.getToken(); 16410 if (ksh instanceof KeySetHandle) { 16411 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16412 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 16413 } 16414 return false; 16415 } 16416 } 16417 16418 public void getUsageStatsIfNoPackageUsageInfo() { 16419 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 16420 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 16421 if (usm == null) { 16422 throw new IllegalStateException("UsageStatsManager must be initialized"); 16423 } 16424 long now = System.currentTimeMillis(); 16425 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 16426 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 16427 String packageName = entry.getKey(); 16428 PackageParser.Package pkg = mPackages.get(packageName); 16429 if (pkg == null) { 16430 continue; 16431 } 16432 UsageStats usage = entry.getValue(); 16433 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 16434 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 16435 } 16436 } 16437 } 16438 16439 /** 16440 * Check and throw if the given before/after packages would be considered a 16441 * downgrade. 16442 */ 16443 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 16444 throws PackageManagerException { 16445 if (after.versionCode < before.mVersionCode) { 16446 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16447 "Update version code " + after.versionCode + " is older than current " 16448 + before.mVersionCode); 16449 } else if (after.versionCode == before.mVersionCode) { 16450 if (after.baseRevisionCode < before.baseRevisionCode) { 16451 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16452 "Update base revision code " + after.baseRevisionCode 16453 + " is older than current " + before.baseRevisionCode); 16454 } 16455 16456 if (!ArrayUtils.isEmpty(after.splitNames)) { 16457 for (int i = 0; i < after.splitNames.length; i++) { 16458 final String splitName = after.splitNames[i]; 16459 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 16460 if (j != -1) { 16461 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 16462 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16463 "Update split " + splitName + " revision code " 16464 + after.splitRevisionCodes[i] + " is older than current " 16465 + before.splitRevisionCodes[j]); 16466 } 16467 } 16468 } 16469 } 16470 } 16471 } 16472 16473 private static class MoveCallbacks extends Handler { 16474 private static final int MSG_CREATED = 1; 16475 private static final int MSG_STATUS_CHANGED = 2; 16476 16477 private final RemoteCallbackList<IPackageMoveObserver> 16478 mCallbacks = new RemoteCallbackList<>(); 16479 16480 private final SparseIntArray mLastStatus = new SparseIntArray(); 16481 16482 public MoveCallbacks(Looper looper) { 16483 super(looper); 16484 } 16485 16486 public void register(IPackageMoveObserver callback) { 16487 mCallbacks.register(callback); 16488 } 16489 16490 public void unregister(IPackageMoveObserver callback) { 16491 mCallbacks.unregister(callback); 16492 } 16493 16494 @Override 16495 public void handleMessage(Message msg) { 16496 final SomeArgs args = (SomeArgs) msg.obj; 16497 final int n = mCallbacks.beginBroadcast(); 16498 for (int i = 0; i < n; i++) { 16499 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 16500 try { 16501 invokeCallback(callback, msg.what, args); 16502 } catch (RemoteException ignored) { 16503 } 16504 } 16505 mCallbacks.finishBroadcast(); 16506 args.recycle(); 16507 } 16508 16509 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 16510 throws RemoteException { 16511 switch (what) { 16512 case MSG_CREATED: { 16513 callback.onCreated(args.argi1, (Bundle) args.arg2); 16514 break; 16515 } 16516 case MSG_STATUS_CHANGED: { 16517 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 16518 break; 16519 } 16520 } 16521 } 16522 16523 private void notifyCreated(int moveId, Bundle extras) { 16524 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 16525 16526 final SomeArgs args = SomeArgs.obtain(); 16527 args.argi1 = moveId; 16528 args.arg2 = extras; 16529 obtainMessage(MSG_CREATED, args).sendToTarget(); 16530 } 16531 16532 private void notifyStatusChanged(int moveId, int status) { 16533 notifyStatusChanged(moveId, status, -1); 16534 } 16535 16536 private void notifyStatusChanged(int moveId, int status, long estMillis) { 16537 Slog.v(TAG, "Move " + moveId + " status " + status); 16538 16539 final SomeArgs args = SomeArgs.obtain(); 16540 args.argi1 = moveId; 16541 args.argi2 = status; 16542 args.arg3 = estMillis; 16543 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 16544 16545 synchronized (mLastStatus) { 16546 mLastStatus.put(moveId, status); 16547 } 16548 } 16549 } 16550 16551 private final class OnPermissionChangeListeners extends Handler { 16552 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 16553 16554 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 16555 new RemoteCallbackList<>(); 16556 16557 public OnPermissionChangeListeners(Looper looper) { 16558 super(looper); 16559 } 16560 16561 @Override 16562 public void handleMessage(Message msg) { 16563 switch (msg.what) { 16564 case MSG_ON_PERMISSIONS_CHANGED: { 16565 final int uid = msg.arg1; 16566 handleOnPermissionsChanged(uid); 16567 } break; 16568 } 16569 } 16570 16571 public void addListenerLocked(IOnPermissionsChangeListener listener) { 16572 mPermissionListeners.register(listener); 16573 16574 } 16575 16576 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 16577 mPermissionListeners.unregister(listener); 16578 } 16579 16580 public void onPermissionsChanged(int uid) { 16581 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 16582 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 16583 } 16584 } 16585 16586 private void handleOnPermissionsChanged(int uid) { 16587 final int count = mPermissionListeners.beginBroadcast(); 16588 try { 16589 for (int i = 0; i < count; i++) { 16590 IOnPermissionsChangeListener callback = mPermissionListeners 16591 .getBroadcastItem(i); 16592 try { 16593 callback.onPermissionsChanged(uid); 16594 } catch (RemoteException e) { 16595 Log.e(TAG, "Permission listener is dead", e); 16596 } 16597 } 16598 } finally { 16599 mPermissionListeners.finishBroadcast(); 16600 } 16601 } 16602 } 16603 16604 private class PackageManagerInternalImpl extends PackageManagerInternal { 16605 @Override 16606 public void setLocationPackagesProvider(PackagesProvider provider) { 16607 synchronized (mPackages) { 16608 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 16609 } 16610 } 16611 16612 @Override 16613 public void setImePackagesProvider(PackagesProvider provider) { 16614 synchronized (mPackages) { 16615 mDefaultPermissionPolicy.setImePackagesProviderLPr(provider); 16616 } 16617 } 16618 16619 @Override 16620 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 16621 synchronized (mPackages) { 16622 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 16623 } 16624 } 16625 16626 @Override 16627 public void setSmsAppPackagesProvider(PackagesProvider provider) { 16628 synchronized (mPackages) { 16629 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 16630 } 16631 } 16632 16633 @Override 16634 public void setDialerAppPackagesProvider(PackagesProvider provider) { 16635 synchronized (mPackages) { 16636 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 16637 } 16638 } 16639 16640 @Override 16641 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 16642 synchronized (mPackages) { 16643 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 16644 } 16645 } 16646 16647 @Override 16648 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 16649 synchronized (mPackages) { 16650 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 16651 } 16652 } 16653 16654 @Override 16655 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 16656 synchronized (mPackages) { 16657 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 16658 packageName, userId); 16659 } 16660 } 16661 16662 @Override 16663 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 16664 synchronized (mPackages) { 16665 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 16666 packageName, userId); 16667 } 16668 } 16669 @Override 16670 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 16671 synchronized (mPackages) { 16672 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 16673 packageName, userId); 16674 } 16675 } 16676 } 16677 16678 @Override 16679 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 16680 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 16681 synchronized (mPackages) { 16682 final long identity = Binder.clearCallingIdentity(); 16683 try { 16684 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 16685 packageNames, userId); 16686 } finally { 16687 Binder.restoreCallingIdentity(identity); 16688 } 16689 } 16690 } 16691 16692 private static void enforceSystemOrPhoneCaller(String tag) { 16693 int callingUid = Binder.getCallingUid(); 16694 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 16695 throw new SecurityException( 16696 "Cannot call " + tag + " from UID " + callingUid); 16697 } 16698 } 16699} 16700