PackageManagerService.java revision 8948c01eb726ec79983472e5597ddac8004f9f44
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.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 60import static android.content.pm.PackageManager.MATCH_ALL; 61import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 62import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 63import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 64import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 65import static android.content.pm.PackageManager.PERMISSION_DENIED; 66import static android.content.pm.PackageManager.PERMISSION_GRANTED; 67import static android.content.pm.PackageParser.isApkFile; 68import static android.os.Process.PACKAGE_INFO_GID; 69import static android.os.Process.SYSTEM_UID; 70import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 71import static android.system.OsConstants.O_CREAT; 72import static android.system.OsConstants.O_RDWR; 73import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 74import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 75import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 76import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 77import static com.android.internal.util.ArrayUtils.appendInt; 78import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 79import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 80import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 81import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 82import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 83import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 84import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 85import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 86import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 87 88import android.Manifest; 89import android.app.ActivityManager; 90import android.app.ActivityManagerNative; 91import android.app.AppGlobals; 92import android.app.IActivityManager; 93import android.app.admin.IDevicePolicyManager; 94import android.app.backup.IBackupManager; 95import android.app.usage.UsageStats; 96import android.app.usage.UsageStatsManager; 97import android.content.BroadcastReceiver; 98import android.content.ComponentName; 99import android.content.Context; 100import android.content.IIntentReceiver; 101import android.content.Intent; 102import android.content.IntentFilter; 103import android.content.IntentSender; 104import android.content.IntentSender.SendIntentException; 105import android.content.ServiceConnection; 106import android.content.pm.ActivityInfo; 107import android.content.pm.ApplicationInfo; 108import android.content.pm.FeatureInfo; 109import android.content.pm.IOnPermissionsChangeListener; 110import android.content.pm.IPackageDataObserver; 111import android.content.pm.IPackageDeleteObserver; 112import android.content.pm.IPackageDeleteObserver2; 113import android.content.pm.IPackageInstallObserver2; 114import android.content.pm.IPackageInstaller; 115import android.content.pm.IPackageManager; 116import android.content.pm.IPackageMoveObserver; 117import android.content.pm.IPackageStatsObserver; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.IntentFilterVerificationInfo; 120import android.content.pm.KeySet; 121import android.content.pm.ManifestDigest; 122import android.content.pm.PackageCleanItem; 123import android.content.pm.PackageInfo; 124import android.content.pm.PackageInfoLite; 125import android.content.pm.PackageInstaller; 126import android.content.pm.PackageManager; 127import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 128import android.content.pm.PackageManagerInternal; 129import android.content.pm.PackageParser; 130import android.content.pm.PackageParser.ActivityIntentInfo; 131import android.content.pm.PackageParser.PackageLite; 132import android.content.pm.PackageParser.PackageParserException; 133import android.content.pm.PackageStats; 134import android.content.pm.PackageUserState; 135import android.content.pm.ParceledListSlice; 136import android.content.pm.PermissionGroupInfo; 137import android.content.pm.PermissionInfo; 138import android.content.pm.ProviderInfo; 139import android.content.pm.ResolveInfo; 140import android.content.pm.ServiceInfo; 141import android.content.pm.Signature; 142import android.content.pm.UserInfo; 143import android.content.pm.VerificationParams; 144import android.content.pm.VerifierDeviceIdentity; 145import android.content.pm.VerifierInfo; 146import android.content.res.Resources; 147import android.hardware.display.DisplayManager; 148import android.net.Uri; 149import android.os.Debug; 150import android.os.Binder; 151import android.os.Build; 152import android.os.Bundle; 153import android.os.Environment; 154import android.os.Environment.UserEnvironment; 155import android.os.FileUtils; 156import android.os.Handler; 157import android.os.IBinder; 158import android.os.Looper; 159import android.os.Message; 160import android.os.Parcel; 161import android.os.ParcelFileDescriptor; 162import android.os.Process; 163import android.os.RemoteCallbackList; 164import android.os.RemoteException; 165import android.os.ResultReceiver; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.SystemClock; 169import android.os.SystemProperties; 170import android.os.Trace; 171import android.os.UserHandle; 172import android.os.UserManager; 173import android.os.storage.IMountService; 174import android.os.storage.MountServiceInternal; 175import android.os.storage.StorageEventListener; 176import android.os.storage.StorageManager; 177import android.os.storage.VolumeInfo; 178import android.os.storage.VolumeRecord; 179import android.security.KeyStore; 180import android.security.SystemKeyStore; 181import android.system.ErrnoException; 182import android.system.Os; 183import android.system.StructStat; 184import android.text.TextUtils; 185import android.text.format.DateUtils; 186import android.util.ArrayMap; 187import android.util.ArraySet; 188import android.util.AtomicFile; 189import android.util.DisplayMetrics; 190import android.util.EventLog; 191import android.util.ExceptionUtils; 192import android.util.Log; 193import android.util.LogPrinter; 194import android.util.MathUtils; 195import android.util.PrintStreamPrinter; 196import android.util.Slog; 197import android.util.SparseArray; 198import android.util.SparseBooleanArray; 199import android.util.SparseIntArray; 200import android.util.Xml; 201import android.view.Display; 202 203import dalvik.system.DexFile; 204import dalvik.system.VMRuntime; 205 206import libcore.io.IoUtils; 207import libcore.util.EmptyArray; 208 209import com.android.internal.R; 210import com.android.internal.annotations.GuardedBy; 211import com.android.internal.app.IMediaContainerService; 212import com.android.internal.app.ResolverActivity; 213import com.android.internal.content.NativeLibraryHelper; 214import com.android.internal.content.PackageHelper; 215import com.android.internal.os.IParcelFileDescriptorFactory; 216import com.android.internal.os.SomeArgs; 217import com.android.internal.os.Zygote; 218import com.android.internal.util.ArrayUtils; 219import com.android.internal.util.FastPrintWriter; 220import com.android.internal.util.FastXmlSerializer; 221import com.android.internal.util.IndentingPrintWriter; 222import com.android.internal.util.Preconditions; 223import com.android.server.EventLogTags; 224import com.android.server.FgThread; 225import com.android.server.IntentResolver; 226import com.android.server.LocalServices; 227import com.android.server.ServiceThread; 228import com.android.server.SystemConfig; 229import com.android.server.Watchdog; 230import com.android.server.pm.PermissionsState.PermissionState; 231import com.android.server.pm.Settings.DatabaseVersion; 232import com.android.server.pm.Settings.VersionInfo; 233import com.android.server.storage.DeviceStorageMonitorInternal; 234 235import org.xmlpull.v1.XmlPullParser; 236import org.xmlpull.v1.XmlPullParserException; 237import org.xmlpull.v1.XmlSerializer; 238 239import java.io.BufferedInputStream; 240import java.io.BufferedOutputStream; 241import java.io.BufferedReader; 242import java.io.ByteArrayInputStream; 243import java.io.ByteArrayOutputStream; 244import java.io.File; 245import java.io.FileDescriptor; 246import java.io.FileNotFoundException; 247import java.io.FileOutputStream; 248import java.io.FileReader; 249import java.io.FilenameFilter; 250import java.io.IOException; 251import java.io.InputStream; 252import java.io.PrintWriter; 253import java.nio.charset.StandardCharsets; 254import java.security.NoSuchAlgorithmException; 255import java.security.PublicKey; 256import java.security.cert.CertificateEncodingException; 257import java.security.cert.CertificateException; 258import java.text.SimpleDateFormat; 259import java.util.ArrayList; 260import java.util.Arrays; 261import java.util.Collection; 262import java.util.Collections; 263import java.util.Comparator; 264import java.util.Date; 265import java.util.Iterator; 266import java.util.List; 267import java.util.Map; 268import java.util.Objects; 269import java.util.Set; 270import java.util.concurrent.CountDownLatch; 271import java.util.concurrent.TimeUnit; 272import java.util.concurrent.atomic.AtomicBoolean; 273import java.util.concurrent.atomic.AtomicInteger; 274import java.util.concurrent.atomic.AtomicLong; 275 276/** 277 * Keep track of all those .apks everywhere. 278 * 279 * This is very central to the platform's security; please run the unit 280 * tests whenever making modifications here: 281 * 282runtest -c android.content.pm.PackageManagerTests frameworks-core 283 * 284 * {@hide} 285 */ 286public class PackageManagerService extends IPackageManager.Stub { 287 static final String TAG = "PackageManager"; 288 static final boolean DEBUG_SETTINGS = false; 289 static final boolean DEBUG_PREFERRED = false; 290 static final boolean DEBUG_UPGRADE = false; 291 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 292 private static final boolean DEBUG_BACKUP = false; 293 private static final boolean DEBUG_INSTALL = false; 294 private static final boolean DEBUG_REMOVE = false; 295 private static final boolean DEBUG_BROADCASTS = false; 296 private static final boolean DEBUG_SHOW_INFO = false; 297 private static final boolean DEBUG_PACKAGE_INFO = false; 298 private static final boolean DEBUG_INTENT_MATCHING = false; 299 private static final boolean DEBUG_PACKAGE_SCANNING = false; 300 private static final boolean DEBUG_VERIFY = false; 301 private static final boolean DEBUG_DEXOPT = false; 302 private static final boolean DEBUG_ABI_SELECTION = false; 303 304 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 305 306 private static final int RADIO_UID = Process.PHONE_UID; 307 private static final int LOG_UID = Process.LOG_UID; 308 private static final int NFC_UID = Process.NFC_UID; 309 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 310 private static final int SHELL_UID = Process.SHELL_UID; 311 312 // Cap the size of permission trees that 3rd party apps can define 313 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 314 315 // Suffix used during package installation when copying/moving 316 // package apks to install directory. 317 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 318 319 static final int SCAN_NO_DEX = 1<<1; 320 static final int SCAN_FORCE_DEX = 1<<2; 321 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 322 static final int SCAN_NEW_INSTALL = 1<<4; 323 static final int SCAN_NO_PATHS = 1<<5; 324 static final int SCAN_UPDATE_TIME = 1<<6; 325 static final int SCAN_DEFER_DEX = 1<<7; 326 static final int SCAN_BOOTING = 1<<8; 327 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 328 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 329 static final int SCAN_REPLACING = 1<<11; 330 static final int SCAN_REQUIRE_KNOWN = 1<<12; 331 static final int SCAN_MOVE = 1<<13; 332 static final int SCAN_INITIAL = 1<<14; 333 334 static final int REMOVE_CHATTY = 1<<16; 335 336 private static final int[] EMPTY_INT_ARRAY = new int[0]; 337 338 /** 339 * Timeout (in milliseconds) after which the watchdog should declare that 340 * our handler thread is wedged. The usual default for such things is one 341 * minute but we sometimes do very lengthy I/O operations on this thread, 342 * such as installing multi-gigabyte applications, so ours needs to be longer. 343 */ 344 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 345 346 /** 347 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 348 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 349 * settings entry if available, otherwise we use the hardcoded default. If it's been 350 * more than this long since the last fstrim, we force one during the boot sequence. 351 * 352 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 353 * one gets run at the next available charging+idle time. This final mandatory 354 * no-fstrim check kicks in only of the other scheduling criteria is never met. 355 */ 356 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 357 358 /** 359 * Whether verification is enabled by default. 360 */ 361 private static final boolean DEFAULT_VERIFY_ENABLE = true; 362 363 /** 364 * The default maximum time to wait for the verification agent to return in 365 * milliseconds. 366 */ 367 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 368 369 /** 370 * The default response for package verification timeout. 371 * 372 * This can be either PackageManager.VERIFICATION_ALLOW or 373 * PackageManager.VERIFICATION_REJECT. 374 */ 375 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 376 377 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 378 379 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 380 DEFAULT_CONTAINER_PACKAGE, 381 "com.android.defcontainer.DefaultContainerService"); 382 383 private static final String KILL_APP_REASON_GIDS_CHANGED = 384 "permission grant or revoke changed gids"; 385 386 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 387 "permissions revoked"; 388 389 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 390 391 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 392 393 /** Permission grant: not grant the permission. */ 394 private static final int GRANT_DENIED = 1; 395 396 /** Permission grant: grant the permission as an install permission. */ 397 private static final int GRANT_INSTALL = 2; 398 399 /** Permission grant: grant the permission as an install permission for a legacy app. */ 400 private static final int GRANT_INSTALL_LEGACY = 3; 401 402 /** Permission grant: grant the permission as a runtime one. */ 403 private static final int GRANT_RUNTIME = 4; 404 405 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 406 private static final int GRANT_UPGRADE = 5; 407 408 /** Canonical intent used to identify what counts as a "web browser" app */ 409 private static final Intent sBrowserIntent; 410 static { 411 sBrowserIntent = new Intent(); 412 sBrowserIntent.setAction(Intent.ACTION_VIEW); 413 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 414 sBrowserIntent.setData(Uri.parse("http:")); 415 } 416 417 final ServiceThread mHandlerThread; 418 419 final PackageHandler mHandler; 420 421 /** 422 * Messages for {@link #mHandler} that need to wait for system ready before 423 * being dispatched. 424 */ 425 private ArrayList<Message> mPostSystemReadyMessages; 426 427 final int mSdkVersion = Build.VERSION.SDK_INT; 428 429 final Context mContext; 430 final boolean mFactoryTest; 431 final boolean mOnlyCore; 432 final boolean mLazyDexOpt; 433 final long mDexOptLRUThresholdInMills; 434 final DisplayMetrics mMetrics; 435 final int mDefParseFlags; 436 final String[] mSeparateProcesses; 437 final boolean mIsUpgrade; 438 439 // This is where all application persistent data goes. 440 final File mAppDataDir; 441 442 // This is where all application persistent data goes for secondary users. 443 final File mUserAppDataDir; 444 445 /** The location for ASEC container files on internal storage. */ 446 final String mAsecInternalPath; 447 448 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 449 // LOCK HELD. Can be called with mInstallLock held. 450 @GuardedBy("mInstallLock") 451 final Installer mInstaller; 452 453 /** Directory where installed third-party apps stored */ 454 final File mAppInstallDir; 455 456 /** 457 * Directory to which applications installed internally have their 458 * 32 bit native libraries copied. 459 */ 460 private File mAppLib32InstallDir; 461 462 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 463 // apps. 464 final File mDrmAppPrivateInstallDir; 465 466 // ---------------------------------------------------------------- 467 468 // Lock for state used when installing and doing other long running 469 // operations. Methods that must be called with this lock held have 470 // the suffix "LI". 471 final Object mInstallLock = new Object(); 472 473 // ---------------------------------------------------------------- 474 475 // Keys are String (package name), values are Package. This also serves 476 // as the lock for the global state. Methods that must be called with 477 // this lock held have the prefix "LP". 478 @GuardedBy("mPackages") 479 final ArrayMap<String, PackageParser.Package> mPackages = 480 new ArrayMap<String, PackageParser.Package>(); 481 482 // Tracks available target package names -> overlay package paths. 483 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 484 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 485 486 /** 487 * Tracks new system packages [received in an OTA] that we expect to 488 * find updated user-installed versions. Keys are package name, values 489 * are package location. 490 */ 491 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 492 493 /** 494 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 495 */ 496 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 497 /** 498 * Whether or not system app permissions should be promoted from install to runtime. 499 */ 500 boolean mPromoteSystemApps; 501 502 final Settings mSettings; 503 boolean mRestoredSettings; 504 505 // System configuration read by SystemConfig. 506 final int[] mGlobalGids; 507 final SparseArray<ArraySet<String>> mSystemPermissions; 508 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 509 510 // If mac_permissions.xml was found for seinfo labeling. 511 boolean mFoundPolicyFile; 512 513 // If a recursive restorecon of /data/data/<pkg> is needed. 514 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 515 516 public static final class SharedLibraryEntry { 517 public final String path; 518 public final String apk; 519 520 SharedLibraryEntry(String _path, String _apk) { 521 path = _path; 522 apk = _apk; 523 } 524 } 525 526 // Currently known shared libraries. 527 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 528 new ArrayMap<String, SharedLibraryEntry>(); 529 530 // All available activities, for your resolving pleasure. 531 final ActivityIntentResolver mActivities = 532 new ActivityIntentResolver(); 533 534 // All available receivers, for your resolving pleasure. 535 final ActivityIntentResolver mReceivers = 536 new ActivityIntentResolver(); 537 538 // All available services, for your resolving pleasure. 539 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 540 541 // All available providers, for your resolving pleasure. 542 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 543 544 // Mapping from provider base names (first directory in content URI codePath) 545 // to the provider information. 546 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 547 new ArrayMap<String, PackageParser.Provider>(); 548 549 // Mapping from instrumentation class names to info about them. 550 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 551 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 552 553 // Mapping from permission names to info about them. 554 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 555 new ArrayMap<String, PackageParser.PermissionGroup>(); 556 557 // Packages whose data we have transfered into another package, thus 558 // should no longer exist. 559 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 560 561 // Broadcast actions that are only available to the system. 562 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 563 564 /** List of packages waiting for verification. */ 565 final SparseArray<PackageVerificationState> mPendingVerification 566 = new SparseArray<PackageVerificationState>(); 567 568 /** Set of packages associated with each app op permission. */ 569 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 570 571 final PackageInstallerService mInstallerService; 572 573 private final PackageDexOptimizer mPackageDexOptimizer; 574 575 private AtomicInteger mNextMoveId = new AtomicInteger(); 576 private final MoveCallbacks mMoveCallbacks; 577 578 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 579 580 // Cache of users who need badging. 581 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 582 583 /** Token for keys in mPendingVerification. */ 584 private int mPendingVerificationToken = 0; 585 586 volatile boolean mSystemReady; 587 volatile boolean mSafeMode; 588 volatile boolean mHasSystemUidErrors; 589 590 ApplicationInfo mAndroidApplication; 591 final ActivityInfo mResolveActivity = new ActivityInfo(); 592 final ResolveInfo mResolveInfo = new ResolveInfo(); 593 ComponentName mResolveComponentName; 594 PackageParser.Package mPlatformPackage; 595 ComponentName mCustomResolverComponentName; 596 597 boolean mResolverReplaced = false; 598 599 private final ComponentName mIntentFilterVerifierComponent; 600 private int mIntentFilterVerificationToken = 0; 601 602 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 603 = new SparseArray<IntentFilterVerificationState>(); 604 605 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 606 new DefaultPermissionGrantPolicy(this); 607 608 private static class IFVerificationParams { 609 PackageParser.Package pkg; 610 boolean replacing; 611 int userId; 612 int verifierUid; 613 614 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 615 int _userId, int _verifierUid) { 616 pkg = _pkg; 617 replacing = _replacing; 618 userId = _userId; 619 replacing = _replacing; 620 verifierUid = _verifierUid; 621 } 622 } 623 624 private interface IntentFilterVerifier<T extends IntentFilter> { 625 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 626 T filter, String packageName); 627 void startVerifications(int userId); 628 void receiveVerificationResponse(int verificationId); 629 } 630 631 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 632 private Context mContext; 633 private ComponentName mIntentFilterVerifierComponent; 634 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 635 636 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 637 mContext = context; 638 mIntentFilterVerifierComponent = verifierComponent; 639 } 640 641 private String getDefaultScheme() { 642 return IntentFilter.SCHEME_HTTPS; 643 } 644 645 @Override 646 public void startVerifications(int userId) { 647 // Launch verifications requests 648 int count = mCurrentIntentFilterVerifications.size(); 649 for (int n=0; n<count; n++) { 650 int verificationId = mCurrentIntentFilterVerifications.get(n); 651 final IntentFilterVerificationState ivs = 652 mIntentFilterVerificationStates.get(verificationId); 653 654 String packageName = ivs.getPackageName(); 655 656 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 657 final int filterCount = filters.size(); 658 ArraySet<String> domainsSet = new ArraySet<>(); 659 for (int m=0; m<filterCount; m++) { 660 PackageParser.ActivityIntentInfo filter = filters.get(m); 661 domainsSet.addAll(filter.getHostsList()); 662 } 663 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 664 synchronized (mPackages) { 665 if (mSettings.createIntentFilterVerificationIfNeededLPw( 666 packageName, domainsList) != null) { 667 scheduleWriteSettingsLocked(); 668 } 669 } 670 sendVerificationRequest(userId, verificationId, ivs); 671 } 672 mCurrentIntentFilterVerifications.clear(); 673 } 674 675 private void sendVerificationRequest(int userId, int verificationId, 676 IntentFilterVerificationState ivs) { 677 678 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 679 verificationIntent.putExtra( 680 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 681 verificationId); 682 verificationIntent.putExtra( 683 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 684 getDefaultScheme()); 685 verificationIntent.putExtra( 686 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 687 ivs.getHostsString()); 688 verificationIntent.putExtra( 689 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 690 ivs.getPackageName()); 691 verificationIntent.setComponent(mIntentFilterVerifierComponent); 692 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 693 694 UserHandle user = new UserHandle(userId); 695 mContext.sendBroadcastAsUser(verificationIntent, user); 696 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 697 "Sending IntentFilter verification broadcast"); 698 } 699 700 public void receiveVerificationResponse(int verificationId) { 701 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 702 703 final boolean verified = ivs.isVerified(); 704 705 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 706 final int count = filters.size(); 707 if (DEBUG_DOMAIN_VERIFICATION) { 708 Slog.i(TAG, "Received verification response " + verificationId 709 + " for " + count + " filters, verified=" + verified); 710 } 711 for (int n=0; n<count; n++) { 712 PackageParser.ActivityIntentInfo filter = filters.get(n); 713 filter.setVerified(verified); 714 715 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 716 + " verified with result:" + verified + " and hosts:" 717 + ivs.getHostsString()); 718 } 719 720 mIntentFilterVerificationStates.remove(verificationId); 721 722 final String packageName = ivs.getPackageName(); 723 IntentFilterVerificationInfo ivi = null; 724 725 synchronized (mPackages) { 726 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 727 } 728 if (ivi == null) { 729 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 730 + verificationId + " packageName:" + packageName); 731 return; 732 } 733 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 734 "Updating IntentFilterVerificationInfo for package " + packageName 735 +" verificationId:" + verificationId); 736 737 synchronized (mPackages) { 738 if (verified) { 739 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 740 } else { 741 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 742 } 743 scheduleWriteSettingsLocked(); 744 745 final int userId = ivs.getUserId(); 746 if (userId != UserHandle.USER_ALL) { 747 final int userStatus = 748 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 749 750 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 751 boolean needUpdate = false; 752 753 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 754 // already been set by the User thru the Disambiguation dialog 755 switch (userStatus) { 756 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 757 if (verified) { 758 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 759 } else { 760 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 761 } 762 needUpdate = true; 763 break; 764 765 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 766 if (verified) { 767 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 768 needUpdate = true; 769 } 770 break; 771 772 default: 773 // Nothing to do 774 } 775 776 if (needUpdate) { 777 mSettings.updateIntentFilterVerificationStatusLPw( 778 packageName, updatedStatus, userId); 779 scheduleWritePackageRestrictionsLocked(userId); 780 } 781 } 782 } 783 } 784 785 @Override 786 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 787 ActivityIntentInfo filter, String packageName) { 788 if (!hasValidDomains(filter)) { 789 return false; 790 } 791 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 792 if (ivs == null) { 793 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 794 packageName); 795 } 796 if (DEBUG_DOMAIN_VERIFICATION) { 797 Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter); 798 } 799 ivs.addFilter(filter); 800 return true; 801 } 802 803 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 804 int userId, int verificationId, String packageName) { 805 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 806 verifierUid, userId, packageName); 807 ivs.setPendingState(); 808 synchronized (mPackages) { 809 mIntentFilterVerificationStates.append(verificationId, ivs); 810 mCurrentIntentFilterVerifications.add(verificationId); 811 } 812 return ivs; 813 } 814 } 815 816 private static boolean hasValidDomains(ActivityIntentInfo filter) { 817 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 818 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 819 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 820 } 821 822 private IntentFilterVerifier mIntentFilterVerifier; 823 824 // Set of pending broadcasts for aggregating enable/disable of components. 825 static class PendingPackageBroadcasts { 826 // for each user id, a map of <package name -> components within that package> 827 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 828 829 public PendingPackageBroadcasts() { 830 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 831 } 832 833 public ArrayList<String> get(int userId, String packageName) { 834 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 835 return packages.get(packageName); 836 } 837 838 public void put(int userId, String packageName, ArrayList<String> components) { 839 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 840 packages.put(packageName, components); 841 } 842 843 public void remove(int userId, String packageName) { 844 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 845 if (packages != null) { 846 packages.remove(packageName); 847 } 848 } 849 850 public void remove(int userId) { 851 mUidMap.remove(userId); 852 } 853 854 public int userIdCount() { 855 return mUidMap.size(); 856 } 857 858 public int userIdAt(int n) { 859 return mUidMap.keyAt(n); 860 } 861 862 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 863 return mUidMap.get(userId); 864 } 865 866 public int size() { 867 // total number of pending broadcast entries across all userIds 868 int num = 0; 869 for (int i = 0; i< mUidMap.size(); i++) { 870 num += mUidMap.valueAt(i).size(); 871 } 872 return num; 873 } 874 875 public void clear() { 876 mUidMap.clear(); 877 } 878 879 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 880 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 881 if (map == null) { 882 map = new ArrayMap<String, ArrayList<String>>(); 883 mUidMap.put(userId, map); 884 } 885 return map; 886 } 887 } 888 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 889 890 // Service Connection to remote media container service to copy 891 // package uri's from external media onto secure containers 892 // or internal storage. 893 private IMediaContainerService mContainerService = null; 894 895 static final int SEND_PENDING_BROADCAST = 1; 896 static final int MCS_BOUND = 3; 897 static final int END_COPY = 4; 898 static final int INIT_COPY = 5; 899 static final int MCS_UNBIND = 6; 900 static final int START_CLEANING_PACKAGE = 7; 901 static final int FIND_INSTALL_LOC = 8; 902 static final int POST_INSTALL = 9; 903 static final int MCS_RECONNECT = 10; 904 static final int MCS_GIVE_UP = 11; 905 static final int UPDATED_MEDIA_STATUS = 12; 906 static final int WRITE_SETTINGS = 13; 907 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 908 static final int PACKAGE_VERIFIED = 15; 909 static final int CHECK_PENDING_VERIFICATION = 16; 910 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 911 static final int INTENT_FILTER_VERIFIED = 18; 912 913 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 914 915 // Delay time in millisecs 916 static final int BROADCAST_DELAY = 10 * 1000; 917 918 static UserManagerService sUserManager; 919 920 // Stores a list of users whose package restrictions file needs to be updated 921 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 922 923 final private DefaultContainerConnection mDefContainerConn = 924 new DefaultContainerConnection(); 925 class DefaultContainerConnection implements ServiceConnection { 926 public void onServiceConnected(ComponentName name, IBinder service) { 927 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 928 IMediaContainerService imcs = 929 IMediaContainerService.Stub.asInterface(service); 930 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 931 } 932 933 public void onServiceDisconnected(ComponentName name) { 934 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 935 } 936 } 937 938 // Recordkeeping of restore-after-install operations that are currently in flight 939 // between the Package Manager and the Backup Manager 940 class PostInstallData { 941 public InstallArgs args; 942 public PackageInstalledInfo res; 943 944 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 945 args = _a; 946 res = _r; 947 } 948 } 949 950 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 951 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 952 953 // XML tags for backup/restore of various bits of state 954 private static final String TAG_PREFERRED_BACKUP = "pa"; 955 private static final String TAG_DEFAULT_APPS = "da"; 956 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 957 958 final String mRequiredVerifierPackage; 959 final String mRequiredInstallerPackage; 960 961 private final PackageUsage mPackageUsage = new PackageUsage(); 962 963 private class PackageUsage { 964 private static final int WRITE_INTERVAL 965 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 966 967 private final Object mFileLock = new Object(); 968 private final AtomicLong mLastWritten = new AtomicLong(0); 969 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 970 971 private boolean mIsHistoricalPackageUsageAvailable = true; 972 973 boolean isHistoricalPackageUsageAvailable() { 974 return mIsHistoricalPackageUsageAvailable; 975 } 976 977 void write(boolean force) { 978 if (force) { 979 writeInternal(); 980 return; 981 } 982 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 983 && !DEBUG_DEXOPT) { 984 return; 985 } 986 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 987 new Thread("PackageUsage_DiskWriter") { 988 @Override 989 public void run() { 990 try { 991 writeInternal(); 992 } finally { 993 mBackgroundWriteRunning.set(false); 994 } 995 } 996 }.start(); 997 } 998 } 999 1000 private void writeInternal() { 1001 synchronized (mPackages) { 1002 synchronized (mFileLock) { 1003 AtomicFile file = getFile(); 1004 FileOutputStream f = null; 1005 try { 1006 f = file.startWrite(); 1007 BufferedOutputStream out = new BufferedOutputStream(f); 1008 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 1009 StringBuilder sb = new StringBuilder(); 1010 for (PackageParser.Package pkg : mPackages.values()) { 1011 if (pkg.mLastPackageUsageTimeInMills == 0) { 1012 continue; 1013 } 1014 sb.setLength(0); 1015 sb.append(pkg.packageName); 1016 sb.append(' '); 1017 sb.append((long)pkg.mLastPackageUsageTimeInMills); 1018 sb.append('\n'); 1019 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 1020 } 1021 out.flush(); 1022 file.finishWrite(f); 1023 } catch (IOException e) { 1024 if (f != null) { 1025 file.failWrite(f); 1026 } 1027 Log.e(TAG, "Failed to write package usage times", e); 1028 } 1029 } 1030 } 1031 mLastWritten.set(SystemClock.elapsedRealtime()); 1032 } 1033 1034 void readLP() { 1035 synchronized (mFileLock) { 1036 AtomicFile file = getFile(); 1037 BufferedInputStream in = null; 1038 try { 1039 in = new BufferedInputStream(file.openRead()); 1040 StringBuffer sb = new StringBuffer(); 1041 while (true) { 1042 String packageName = readToken(in, sb, ' '); 1043 if (packageName == null) { 1044 break; 1045 } 1046 String timeInMillisString = readToken(in, sb, '\n'); 1047 if (timeInMillisString == null) { 1048 throw new IOException("Failed to find last usage time for package " 1049 + packageName); 1050 } 1051 PackageParser.Package pkg = mPackages.get(packageName); 1052 if (pkg == null) { 1053 continue; 1054 } 1055 long timeInMillis; 1056 try { 1057 timeInMillis = Long.parseLong(timeInMillisString.toString()); 1058 } catch (NumberFormatException e) { 1059 throw new IOException("Failed to parse " + timeInMillisString 1060 + " as a long.", e); 1061 } 1062 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1063 } 1064 } catch (FileNotFoundException expected) { 1065 mIsHistoricalPackageUsageAvailable = false; 1066 } catch (IOException e) { 1067 Log.w(TAG, "Failed to read package usage times", e); 1068 } finally { 1069 IoUtils.closeQuietly(in); 1070 } 1071 } 1072 mLastWritten.set(SystemClock.elapsedRealtime()); 1073 } 1074 1075 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1076 throws IOException { 1077 sb.setLength(0); 1078 while (true) { 1079 int ch = in.read(); 1080 if (ch == -1) { 1081 if (sb.length() == 0) { 1082 return null; 1083 } 1084 throw new IOException("Unexpected EOF"); 1085 } 1086 if (ch == endOfToken) { 1087 return sb.toString(); 1088 } 1089 sb.append((char)ch); 1090 } 1091 } 1092 1093 private AtomicFile getFile() { 1094 File dataDir = Environment.getDataDirectory(); 1095 File systemDir = new File(dataDir, "system"); 1096 File fname = new File(systemDir, "package-usage.list"); 1097 return new AtomicFile(fname); 1098 } 1099 } 1100 1101 class PackageHandler extends Handler { 1102 private boolean mBound = false; 1103 final ArrayList<HandlerParams> mPendingInstalls = 1104 new ArrayList<HandlerParams>(); 1105 1106 private boolean connectToService() { 1107 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1108 " DefaultContainerService"); 1109 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1110 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1111 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1112 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1113 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1114 mBound = true; 1115 return true; 1116 } 1117 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1118 return false; 1119 } 1120 1121 private void disconnectService() { 1122 mContainerService = null; 1123 mBound = false; 1124 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1125 mContext.unbindService(mDefContainerConn); 1126 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1127 } 1128 1129 PackageHandler(Looper looper) { 1130 super(looper); 1131 } 1132 1133 public void handleMessage(Message msg) { 1134 try { 1135 doHandleMessage(msg); 1136 } finally { 1137 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1138 } 1139 } 1140 1141 void doHandleMessage(Message msg) { 1142 switch (msg.what) { 1143 case INIT_COPY: { 1144 HandlerParams params = (HandlerParams) msg.obj; 1145 int idx = mPendingInstalls.size(); 1146 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1147 // If a bind was already initiated we dont really 1148 // need to do anything. The pending install 1149 // will be processed later on. 1150 if (!mBound) { 1151 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1152 System.identityHashCode(mHandler)); 1153 // If this is the only one pending we might 1154 // have to bind to the service again. 1155 if (!connectToService()) { 1156 Slog.e(TAG, "Failed to bind to media container service"); 1157 params.serviceError(); 1158 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1159 System.identityHashCode(mHandler)); 1160 if (params.traceMethod != null) { 1161 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1162 params.traceCookie); 1163 } 1164 return; 1165 } else { 1166 // Once we bind to the service, the first 1167 // pending request will be processed. 1168 mPendingInstalls.add(idx, params); 1169 } 1170 } else { 1171 mPendingInstalls.add(idx, params); 1172 // Already bound to the service. Just make 1173 // sure we trigger off processing the first request. 1174 if (idx == 0) { 1175 mHandler.sendEmptyMessage(MCS_BOUND); 1176 } 1177 } 1178 break; 1179 } 1180 case MCS_BOUND: { 1181 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1182 if (msg.obj != null) { 1183 mContainerService = (IMediaContainerService) msg.obj; 1184 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1185 System.identityHashCode(mHandler)); 1186 } 1187 if (mContainerService == null) { 1188 if (!mBound) { 1189 // Something seriously wrong since we are not bound and we are not 1190 // waiting for connection. Bail out. 1191 Slog.e(TAG, "Cannot bind to media container service"); 1192 for (HandlerParams params : mPendingInstalls) { 1193 // Indicate service bind error 1194 params.serviceError(); 1195 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1196 System.identityHashCode(params)); 1197 if (params.traceMethod != null) { 1198 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1199 params.traceMethod, params.traceCookie); 1200 } 1201 return; 1202 } 1203 mPendingInstalls.clear(); 1204 } else { 1205 Slog.w(TAG, "Waiting to connect to media container service"); 1206 } 1207 } else if (mPendingInstalls.size() > 0) { 1208 HandlerParams params = mPendingInstalls.get(0); 1209 if (params != null) { 1210 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1211 System.identityHashCode(params)); 1212 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1213 if (params.startCopy()) { 1214 // We are done... look for more work or to 1215 // go idle. 1216 if (DEBUG_SD_INSTALL) Log.i(TAG, 1217 "Checking for more work or unbind..."); 1218 // Delete pending install 1219 if (mPendingInstalls.size() > 0) { 1220 mPendingInstalls.remove(0); 1221 } 1222 if (mPendingInstalls.size() == 0) { 1223 if (mBound) { 1224 if (DEBUG_SD_INSTALL) Log.i(TAG, 1225 "Posting delayed MCS_UNBIND"); 1226 removeMessages(MCS_UNBIND); 1227 Message ubmsg = obtainMessage(MCS_UNBIND); 1228 // Unbind after a little delay, to avoid 1229 // continual thrashing. 1230 sendMessageDelayed(ubmsg, 10000); 1231 } 1232 } else { 1233 // There are more pending requests in queue. 1234 // Just post MCS_BOUND message to trigger processing 1235 // of next pending install. 1236 if (DEBUG_SD_INSTALL) Log.i(TAG, 1237 "Posting MCS_BOUND for next work"); 1238 mHandler.sendEmptyMessage(MCS_BOUND); 1239 } 1240 } 1241 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1242 } 1243 } else { 1244 // Should never happen ideally. 1245 Slog.w(TAG, "Empty queue"); 1246 } 1247 break; 1248 } 1249 case MCS_RECONNECT: { 1250 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1251 if (mPendingInstalls.size() > 0) { 1252 if (mBound) { 1253 disconnectService(); 1254 } 1255 if (!connectToService()) { 1256 Slog.e(TAG, "Failed to bind to media container service"); 1257 for (HandlerParams params : mPendingInstalls) { 1258 // Indicate service bind error 1259 params.serviceError(); 1260 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1261 System.identityHashCode(params)); 1262 } 1263 mPendingInstalls.clear(); 1264 } 1265 } 1266 break; 1267 } 1268 case MCS_UNBIND: { 1269 // If there is no actual work left, then time to unbind. 1270 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1271 1272 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1273 if (mBound) { 1274 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1275 1276 disconnectService(); 1277 } 1278 } else if (mPendingInstalls.size() > 0) { 1279 // There are more pending requests in queue. 1280 // Just post MCS_BOUND message to trigger processing 1281 // of next pending install. 1282 mHandler.sendEmptyMessage(MCS_BOUND); 1283 } 1284 1285 break; 1286 } 1287 case MCS_GIVE_UP: { 1288 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1289 HandlerParams params = mPendingInstalls.remove(0); 1290 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1291 System.identityHashCode(params)); 1292 break; 1293 } 1294 case SEND_PENDING_BROADCAST: { 1295 String packages[]; 1296 ArrayList<String> components[]; 1297 int size = 0; 1298 int uids[]; 1299 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1300 synchronized (mPackages) { 1301 if (mPendingBroadcasts == null) { 1302 return; 1303 } 1304 size = mPendingBroadcasts.size(); 1305 if (size <= 0) { 1306 // Nothing to be done. Just return 1307 return; 1308 } 1309 packages = new String[size]; 1310 components = new ArrayList[size]; 1311 uids = new int[size]; 1312 int i = 0; // filling out the above arrays 1313 1314 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1315 int packageUserId = mPendingBroadcasts.userIdAt(n); 1316 Iterator<Map.Entry<String, ArrayList<String>>> it 1317 = mPendingBroadcasts.packagesForUserId(packageUserId) 1318 .entrySet().iterator(); 1319 while (it.hasNext() && i < size) { 1320 Map.Entry<String, ArrayList<String>> ent = it.next(); 1321 packages[i] = ent.getKey(); 1322 components[i] = ent.getValue(); 1323 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1324 uids[i] = (ps != null) 1325 ? UserHandle.getUid(packageUserId, ps.appId) 1326 : -1; 1327 i++; 1328 } 1329 } 1330 size = i; 1331 mPendingBroadcasts.clear(); 1332 } 1333 // Send broadcasts 1334 for (int i = 0; i < size; i++) { 1335 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1336 } 1337 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1338 break; 1339 } 1340 case START_CLEANING_PACKAGE: { 1341 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1342 final String packageName = (String)msg.obj; 1343 final int userId = msg.arg1; 1344 final boolean andCode = msg.arg2 != 0; 1345 synchronized (mPackages) { 1346 if (userId == UserHandle.USER_ALL) { 1347 int[] users = sUserManager.getUserIds(); 1348 for (int user : users) { 1349 mSettings.addPackageToCleanLPw( 1350 new PackageCleanItem(user, packageName, andCode)); 1351 } 1352 } else { 1353 mSettings.addPackageToCleanLPw( 1354 new PackageCleanItem(userId, packageName, andCode)); 1355 } 1356 } 1357 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1358 startCleaningPackages(); 1359 } break; 1360 case POST_INSTALL: { 1361 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1362 PostInstallData data = mRunningInstalls.get(msg.arg1); 1363 mRunningInstalls.delete(msg.arg1); 1364 boolean deleteOld = false; 1365 1366 if (data != null) { 1367 InstallArgs args = data.args; 1368 PackageInstalledInfo res = data.res; 1369 1370 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1371 final String packageName = res.pkg.applicationInfo.packageName; 1372 res.removedInfo.sendBroadcast(false, true, false); 1373 Bundle extras = new Bundle(1); 1374 extras.putInt(Intent.EXTRA_UID, res.uid); 1375 1376 // Now that we successfully installed the package, grant runtime 1377 // permissions if requested before broadcasting the install. 1378 if ((args.installFlags 1379 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { 1380 grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(), 1381 args.installGrantPermissions); 1382 } 1383 1384 // Determine the set of users who are adding this 1385 // package for the first time vs. those who are seeing 1386 // an update. 1387 int[] firstUsers; 1388 int[] updateUsers = new int[0]; 1389 if (res.origUsers == null || res.origUsers.length == 0) { 1390 firstUsers = res.newUsers; 1391 } else { 1392 firstUsers = new int[0]; 1393 for (int i=0; i<res.newUsers.length; i++) { 1394 int user = res.newUsers[i]; 1395 boolean isNew = true; 1396 for (int j=0; j<res.origUsers.length; j++) { 1397 if (res.origUsers[j] == user) { 1398 isNew = false; 1399 break; 1400 } 1401 } 1402 if (isNew) { 1403 int[] newFirst = new int[firstUsers.length+1]; 1404 System.arraycopy(firstUsers, 0, newFirst, 0, 1405 firstUsers.length); 1406 newFirst[firstUsers.length] = user; 1407 firstUsers = newFirst; 1408 } else { 1409 int[] newUpdate = new int[updateUsers.length+1]; 1410 System.arraycopy(updateUsers, 0, newUpdate, 0, 1411 updateUsers.length); 1412 newUpdate[updateUsers.length] = user; 1413 updateUsers = newUpdate; 1414 } 1415 } 1416 } 1417 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1418 packageName, extras, null, null, firstUsers); 1419 final boolean update = res.removedInfo.removedPackage != null; 1420 if (update) { 1421 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1422 } 1423 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1424 packageName, extras, null, null, updateUsers); 1425 if (update) { 1426 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1427 packageName, extras, null, null, updateUsers); 1428 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1429 null, null, packageName, null, updateUsers); 1430 1431 // treat asec-hosted packages like removable media on upgrade 1432 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1433 if (DEBUG_INSTALL) { 1434 Slog.i(TAG, "upgrading pkg " + res.pkg 1435 + " is ASEC-hosted -> AVAILABLE"); 1436 } 1437 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1438 ArrayList<String> pkgList = new ArrayList<String>(1); 1439 pkgList.add(packageName); 1440 sendResourcesChangedBroadcast(true, true, 1441 pkgList,uidArray, null); 1442 } 1443 } 1444 if (res.removedInfo.args != null) { 1445 // Remove the replaced package's older resources safely now 1446 deleteOld = true; 1447 } 1448 1449 // If this app is a browser and it's newly-installed for some 1450 // users, clear any default-browser state in those users 1451 if (firstUsers.length > 0) { 1452 // the app's nature doesn't depend on the user, so we can just 1453 // check its browser nature in any user and generalize. 1454 if (packageIsBrowser(packageName, firstUsers[0])) { 1455 synchronized (mPackages) { 1456 for (int userId : firstUsers) { 1457 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1458 } 1459 } 1460 } 1461 } 1462 // Log current value of "unknown sources" setting 1463 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1464 getUnknownSourcesSettings()); 1465 } 1466 // Force a gc to clear up things 1467 Runtime.getRuntime().gc(); 1468 // We delete after a gc for applications on sdcard. 1469 if (deleteOld) { 1470 synchronized (mInstallLock) { 1471 res.removedInfo.args.doPostDeleteLI(true); 1472 } 1473 } 1474 if (args.observer != null) { 1475 try { 1476 Bundle extras = extrasForInstallResult(res); 1477 args.observer.onPackageInstalled(res.name, res.returnCode, 1478 res.returnMsg, extras); 1479 } catch (RemoteException e) { 1480 Slog.i(TAG, "Observer no longer exists."); 1481 } 1482 } 1483 if (args.traceMethod != null) { 1484 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1485 args.traceCookie); 1486 } 1487 return; 1488 } else { 1489 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1490 } 1491 1492 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1493 } break; 1494 case UPDATED_MEDIA_STATUS: { 1495 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1496 boolean reportStatus = msg.arg1 == 1; 1497 boolean doGc = msg.arg2 == 1; 1498 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1499 if (doGc) { 1500 // Force a gc to clear up stale containers. 1501 Runtime.getRuntime().gc(); 1502 } 1503 if (msg.obj != null) { 1504 @SuppressWarnings("unchecked") 1505 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1506 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1507 // Unload containers 1508 unloadAllContainers(args); 1509 } 1510 if (reportStatus) { 1511 try { 1512 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1513 PackageHelper.getMountService().finishMediaUpdate(); 1514 } catch (RemoteException e) { 1515 Log.e(TAG, "MountService not running?"); 1516 } 1517 } 1518 } break; 1519 case WRITE_SETTINGS: { 1520 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1521 synchronized (mPackages) { 1522 removeMessages(WRITE_SETTINGS); 1523 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1524 mSettings.writeLPr(); 1525 mDirtyUsers.clear(); 1526 } 1527 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1528 } break; 1529 case WRITE_PACKAGE_RESTRICTIONS: { 1530 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1531 synchronized (mPackages) { 1532 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1533 for (int userId : mDirtyUsers) { 1534 mSettings.writePackageRestrictionsLPr(userId); 1535 } 1536 mDirtyUsers.clear(); 1537 } 1538 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1539 } break; 1540 case CHECK_PENDING_VERIFICATION: { 1541 final int verificationId = msg.arg1; 1542 final PackageVerificationState state = mPendingVerification.get(verificationId); 1543 1544 if ((state != null) && !state.timeoutExtended()) { 1545 final InstallArgs args = state.getInstallArgs(); 1546 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1547 1548 Slog.i(TAG, "Verification timed out for " + originUri); 1549 mPendingVerification.remove(verificationId); 1550 1551 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1552 1553 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1554 Slog.i(TAG, "Continuing with installation of " + originUri); 1555 state.setVerifierResponse(Binder.getCallingUid(), 1556 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1557 broadcastPackageVerified(verificationId, originUri, 1558 PackageManager.VERIFICATION_ALLOW, 1559 state.getInstallArgs().getUser()); 1560 try { 1561 ret = args.copyApk(mContainerService, true); 1562 } catch (RemoteException e) { 1563 Slog.e(TAG, "Could not contact the ContainerService"); 1564 } 1565 } else { 1566 broadcastPackageVerified(verificationId, originUri, 1567 PackageManager.VERIFICATION_REJECT, 1568 state.getInstallArgs().getUser()); 1569 } 1570 1571 Trace.asyncTraceEnd( 1572 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1573 1574 processPendingInstall(args, ret); 1575 mHandler.sendEmptyMessage(MCS_UNBIND); 1576 } 1577 break; 1578 } 1579 case PACKAGE_VERIFIED: { 1580 final int verificationId = msg.arg1; 1581 1582 final PackageVerificationState state = mPendingVerification.get(verificationId); 1583 if (state == null) { 1584 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1585 break; 1586 } 1587 1588 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1589 1590 state.setVerifierResponse(response.callerUid, response.code); 1591 1592 if (state.isVerificationComplete()) { 1593 mPendingVerification.remove(verificationId); 1594 1595 final InstallArgs args = state.getInstallArgs(); 1596 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1597 1598 int ret; 1599 if (state.isInstallAllowed()) { 1600 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1601 broadcastPackageVerified(verificationId, originUri, 1602 response.code, state.getInstallArgs().getUser()); 1603 try { 1604 ret = args.copyApk(mContainerService, true); 1605 } catch (RemoteException e) { 1606 Slog.e(TAG, "Could not contact the ContainerService"); 1607 } 1608 } else { 1609 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1610 } 1611 1612 Trace.asyncTraceEnd( 1613 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1614 1615 processPendingInstall(args, ret); 1616 mHandler.sendEmptyMessage(MCS_UNBIND); 1617 } 1618 1619 break; 1620 } 1621 case START_INTENT_FILTER_VERIFICATIONS: { 1622 IFVerificationParams params = (IFVerificationParams) msg.obj; 1623 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1624 params.replacing, params.pkg); 1625 break; 1626 } 1627 case INTENT_FILTER_VERIFIED: { 1628 final int verificationId = msg.arg1; 1629 1630 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1631 verificationId); 1632 if (state == null) { 1633 Slog.w(TAG, "Invalid IntentFilter verification token " 1634 + verificationId + " received"); 1635 break; 1636 } 1637 1638 final int userId = state.getUserId(); 1639 1640 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1641 "Processing IntentFilter verification with token:" 1642 + verificationId + " and userId:" + userId); 1643 1644 final IntentFilterVerificationResponse response = 1645 (IntentFilterVerificationResponse) msg.obj; 1646 1647 state.setVerifierResponse(response.callerUid, response.code); 1648 1649 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1650 "IntentFilter verification with token:" + verificationId 1651 + " and userId:" + userId 1652 + " is settings verifier response with response code:" 1653 + response.code); 1654 1655 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1656 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1657 + response.getFailedDomainsString()); 1658 } 1659 1660 if (state.isVerificationComplete()) { 1661 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1662 } else { 1663 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1664 "IntentFilter verification with token:" + verificationId 1665 + " was not said to be complete"); 1666 } 1667 1668 break; 1669 } 1670 } 1671 } 1672 } 1673 1674 private StorageEventListener mStorageListener = new StorageEventListener() { 1675 @Override 1676 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1677 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1678 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1679 final String volumeUuid = vol.getFsUuid(); 1680 1681 // Clean up any users or apps that were removed or recreated 1682 // while this volume was missing 1683 reconcileUsers(volumeUuid); 1684 reconcileApps(volumeUuid); 1685 1686 // Clean up any install sessions that expired or were 1687 // cancelled while this volume was missing 1688 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1689 1690 loadPrivatePackages(vol); 1691 1692 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1693 unloadPrivatePackages(vol); 1694 } 1695 } 1696 1697 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1698 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1699 updateExternalMediaStatus(true, false); 1700 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1701 updateExternalMediaStatus(false, false); 1702 } 1703 } 1704 } 1705 1706 @Override 1707 public void onVolumeForgotten(String fsUuid) { 1708 if (TextUtils.isEmpty(fsUuid)) { 1709 Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1710 return; 1711 } 1712 1713 // Remove any apps installed on the forgotten volume 1714 synchronized (mPackages) { 1715 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1716 for (PackageSetting ps : packages) { 1717 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1718 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1719 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1720 } 1721 1722 mSettings.onVolumeForgotten(fsUuid); 1723 mSettings.writeLPr(); 1724 } 1725 } 1726 }; 1727 1728 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId, 1729 String[] grantedPermissions) { 1730 if (userId >= UserHandle.USER_SYSTEM) { 1731 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1732 } else if (userId == UserHandle.USER_ALL) { 1733 final int[] userIds; 1734 synchronized (mPackages) { 1735 userIds = UserManagerService.getInstance().getUserIds(); 1736 } 1737 for (int someUserId : userIds) { 1738 grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions); 1739 } 1740 } 1741 1742 // We could have touched GID membership, so flush out packages.list 1743 synchronized (mPackages) { 1744 mSettings.writePackageListLPr(); 1745 } 1746 } 1747 1748 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1749 String[] grantedPermissions) { 1750 SettingBase sb = (SettingBase) pkg.mExtras; 1751 if (sb == null) { 1752 return; 1753 } 1754 1755 PermissionsState permissionsState = sb.getPermissionsState(); 1756 1757 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1758 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1759 1760 synchronized (mPackages) { 1761 for (String permission : pkg.requestedPermissions) { 1762 BasePermission bp = mSettings.mPermissions.get(permission); 1763 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1764 && (grantedPermissions == null 1765 || ArrayUtils.contains(grantedPermissions, permission))) { 1766 final int flags = permissionsState.getPermissionFlags(permission, userId); 1767 // Installer cannot change immutable permissions. 1768 if ((flags & immutableFlags) == 0) { 1769 grantRuntimePermission(pkg.packageName, permission, userId); 1770 } 1771 } 1772 } 1773 } 1774 } 1775 1776 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1777 Bundle extras = null; 1778 switch (res.returnCode) { 1779 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1780 extras = new Bundle(); 1781 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1782 res.origPermission); 1783 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1784 res.origPackage); 1785 break; 1786 } 1787 case PackageManager.INSTALL_SUCCEEDED: { 1788 extras = new Bundle(); 1789 extras.putBoolean(Intent.EXTRA_REPLACING, 1790 res.removedInfo != null && res.removedInfo.removedPackage != null); 1791 break; 1792 } 1793 } 1794 return extras; 1795 } 1796 1797 void scheduleWriteSettingsLocked() { 1798 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1799 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1800 } 1801 } 1802 1803 void scheduleWritePackageRestrictionsLocked(int userId) { 1804 if (!sUserManager.exists(userId)) return; 1805 mDirtyUsers.add(userId); 1806 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1807 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1808 } 1809 } 1810 1811 public static PackageManagerService main(Context context, Installer installer, 1812 boolean factoryTest, boolean onlyCore) { 1813 PackageManagerService m = new PackageManagerService(context, installer, 1814 factoryTest, onlyCore); 1815 ServiceManager.addService("package", m); 1816 return m; 1817 } 1818 1819 static String[] splitString(String str, char sep) { 1820 int count = 1; 1821 int i = 0; 1822 while ((i=str.indexOf(sep, i)) >= 0) { 1823 count++; 1824 i++; 1825 } 1826 1827 String[] res = new String[count]; 1828 i=0; 1829 count = 0; 1830 int lastI=0; 1831 while ((i=str.indexOf(sep, i)) >= 0) { 1832 res[count] = str.substring(lastI, i); 1833 count++; 1834 i++; 1835 lastI = i; 1836 } 1837 res[count] = str.substring(lastI, str.length()); 1838 return res; 1839 } 1840 1841 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1842 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1843 Context.DISPLAY_SERVICE); 1844 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1845 } 1846 1847 public PackageManagerService(Context context, Installer installer, 1848 boolean factoryTest, boolean onlyCore) { 1849 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1850 SystemClock.uptimeMillis()); 1851 1852 if (mSdkVersion <= 0) { 1853 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1854 } 1855 1856 mContext = context; 1857 mFactoryTest = factoryTest; 1858 mOnlyCore = onlyCore; 1859 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1860 mMetrics = new DisplayMetrics(); 1861 mSettings = new Settings(mPackages); 1862 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1863 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1864 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1865 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1866 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1867 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1868 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1869 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1870 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1871 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1872 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1873 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1874 1875 // TODO: add a property to control this? 1876 long dexOptLRUThresholdInMinutes; 1877 if (mLazyDexOpt) { 1878 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1879 } else { 1880 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1881 } 1882 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1883 1884 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1885 if (separateProcesses != null && separateProcesses.length() > 0) { 1886 if ("*".equals(separateProcesses)) { 1887 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1888 mSeparateProcesses = null; 1889 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1890 } else { 1891 mDefParseFlags = 0; 1892 mSeparateProcesses = separateProcesses.split(","); 1893 Slog.w(TAG, "Running with debug.separate_processes: " 1894 + separateProcesses); 1895 } 1896 } else { 1897 mDefParseFlags = 0; 1898 mSeparateProcesses = null; 1899 } 1900 1901 mInstaller = installer; 1902 mPackageDexOptimizer = new PackageDexOptimizer(this); 1903 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 1904 1905 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 1906 FgThread.get().getLooper()); 1907 1908 getDefaultDisplayMetrics(context, mMetrics); 1909 1910 SystemConfig systemConfig = SystemConfig.getInstance(); 1911 mGlobalGids = systemConfig.getGlobalGids(); 1912 mSystemPermissions = systemConfig.getSystemPermissions(); 1913 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1914 1915 synchronized (mInstallLock) { 1916 // writer 1917 synchronized (mPackages) { 1918 mHandlerThread = new ServiceThread(TAG, 1919 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1920 mHandlerThread.start(); 1921 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1922 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1923 1924 File dataDir = Environment.getDataDirectory(); 1925 mAppDataDir = new File(dataDir, "data"); 1926 mAppInstallDir = new File(dataDir, "app"); 1927 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1928 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1929 mUserAppDataDir = new File(dataDir, "user"); 1930 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1931 1932 sUserManager = new UserManagerService(context, this, 1933 mInstallLock, mPackages); 1934 1935 // Propagate permission configuration in to package manager. 1936 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1937 = systemConfig.getPermissions(); 1938 for (int i=0; i<permConfig.size(); i++) { 1939 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1940 BasePermission bp = mSettings.mPermissions.get(perm.name); 1941 if (bp == null) { 1942 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1943 mSettings.mPermissions.put(perm.name, bp); 1944 } 1945 if (perm.gids != null) { 1946 bp.setGids(perm.gids, perm.perUser); 1947 } 1948 } 1949 1950 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1951 for (int i=0; i<libConfig.size(); i++) { 1952 mSharedLibraries.put(libConfig.keyAt(i), 1953 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1954 } 1955 1956 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1957 1958 mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false)); 1959 1960 String customResolverActivity = Resources.getSystem().getString( 1961 R.string.config_customResolverActivity); 1962 if (TextUtils.isEmpty(customResolverActivity)) { 1963 customResolverActivity = null; 1964 } else { 1965 mCustomResolverComponentName = ComponentName.unflattenFromString( 1966 customResolverActivity); 1967 } 1968 1969 long startTime = SystemClock.uptimeMillis(); 1970 1971 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1972 startTime); 1973 1974 // Set flag to monitor and not change apk file paths when 1975 // scanning install directories. 1976 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 1977 1978 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1979 1980 /** 1981 * Add everything in the in the boot class path to the 1982 * list of process files because dexopt will have been run 1983 * if necessary during zygote startup. 1984 */ 1985 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1986 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1987 1988 if (bootClassPath != null) { 1989 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1990 for (String element : bootClassPathElements) { 1991 alreadyDexOpted.add(element); 1992 } 1993 } else { 1994 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1995 } 1996 1997 if (systemServerClassPath != null) { 1998 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1999 for (String element : systemServerClassPathElements) { 2000 alreadyDexOpted.add(element); 2001 } 2002 } else { 2003 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2004 } 2005 2006 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2007 final String[] dexCodeInstructionSets = 2008 getDexCodeInstructionSets( 2009 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2010 2011 /** 2012 * Ensure all external libraries have had dexopt run on them. 2013 */ 2014 if (mSharedLibraries.size() > 0) { 2015 // NOTE: For now, we're compiling these system "shared libraries" 2016 // (and framework jars) into all available architectures. It's possible 2017 // to compile them only when we come across an app that uses them (there's 2018 // already logic for that in scanPackageLI) but that adds some complexity. 2019 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2020 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2021 final String lib = libEntry.path; 2022 if (lib == null) { 2023 continue; 2024 } 2025 2026 try { 2027 int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); 2028 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2029 alreadyDexOpted.add(lib); 2030 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2031 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/); 2032 } 2033 } catch (FileNotFoundException e) { 2034 Slog.w(TAG, "Library not found: " + lib); 2035 } catch (IOException e) { 2036 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2037 + e.getMessage()); 2038 } 2039 } 2040 } 2041 } 2042 2043 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2044 2045 // Gross hack for now: we know this file doesn't contain any 2046 // code, so don't dexopt it to avoid the resulting log spew. 2047 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 2048 2049 // Gross hack for now: we know this file is only part of 2050 // the boot class path for art, so don't dexopt it to 2051 // avoid the resulting log spew. 2052 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 2053 2054 /** 2055 * There are a number of commands implemented in Java, which 2056 * we currently need to do the dexopt on so that they can be 2057 * run from a non-root shell. 2058 */ 2059 String[] frameworkFiles = frameworkDir.list(); 2060 if (frameworkFiles != null) { 2061 // TODO: We could compile these only for the most preferred ABI. We should 2062 // first double check that the dex files for these commands are not referenced 2063 // by other system apps. 2064 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2065 for (int i=0; i<frameworkFiles.length; i++) { 2066 File libPath = new File(frameworkDir, frameworkFiles[i]); 2067 String path = libPath.getPath(); 2068 // Skip the file if we already did it. 2069 if (alreadyDexOpted.contains(path)) { 2070 continue; 2071 } 2072 // Skip the file if it is not a type we want to dexopt. 2073 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 2074 continue; 2075 } 2076 try { 2077 int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); 2078 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2079 mInstaller.dexopt(path, Process.SYSTEM_UID, dexCodeInstructionSet, 2080 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/); 2081 } 2082 } catch (FileNotFoundException e) { 2083 Slog.w(TAG, "Jar not found: " + path); 2084 } catch (IOException e) { 2085 Slog.w(TAG, "Exception reading jar: " + path, e); 2086 } 2087 } 2088 } 2089 } 2090 2091 final VersionInfo ver = mSettings.getInternalVersion(); 2092 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2093 // when upgrading from pre-M, promote system app permissions from install to runtime 2094 mPromoteSystemApps = 2095 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2096 2097 // save off the names of pre-existing system packages prior to scanning; we don't 2098 // want to automatically grant runtime permissions for new system apps 2099 if (mPromoteSystemApps) { 2100 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2101 while (pkgSettingIter.hasNext()) { 2102 PackageSetting ps = pkgSettingIter.next(); 2103 if (isSystemApp(ps)) { 2104 mExistingSystemPackages.add(ps.name); 2105 } 2106 } 2107 } 2108 2109 // Collect vendor overlay packages. 2110 // (Do this before scanning any apps.) 2111 // For security and version matching reason, only consider 2112 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2113 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2114 scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2115 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2116 2117 // Find base frameworks (resource packages without code). 2118 scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2119 | PackageParser.PARSE_IS_SYSTEM_DIR 2120 | PackageParser.PARSE_IS_PRIVILEGED, 2121 scanFlags | SCAN_NO_DEX, 0); 2122 2123 // Collected privileged system packages. 2124 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2125 scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2126 | PackageParser.PARSE_IS_SYSTEM_DIR 2127 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2128 2129 // Collect ordinary system packages. 2130 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2131 scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2132 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2133 2134 // Collect all vendor packages. 2135 File vendorAppDir = new File("/vendor/app"); 2136 try { 2137 vendorAppDir = vendorAppDir.getCanonicalFile(); 2138 } catch (IOException e) { 2139 // failed to look up canonical path, continue with original one 2140 } 2141 scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2142 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2143 2144 // Collect all OEM packages. 2145 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2146 scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2147 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2148 2149 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 2150 mInstaller.moveFiles(); 2151 2152 // Prune any system packages that no longer exist. 2153 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2154 if (!mOnlyCore) { 2155 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2156 while (psit.hasNext()) { 2157 PackageSetting ps = psit.next(); 2158 2159 /* 2160 * If this is not a system app, it can't be a 2161 * disable system app. 2162 */ 2163 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2164 continue; 2165 } 2166 2167 /* 2168 * If the package is scanned, it's not erased. 2169 */ 2170 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2171 if (scannedPkg != null) { 2172 /* 2173 * If the system app is both scanned and in the 2174 * disabled packages list, then it must have been 2175 * added via OTA. Remove it from the currently 2176 * scanned package so the previously user-installed 2177 * application can be scanned. 2178 */ 2179 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2180 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2181 + ps.name + "; removing system app. Last known codePath=" 2182 + ps.codePathString + ", installStatus=" + ps.installStatus 2183 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2184 + scannedPkg.mVersionCode); 2185 removePackageLI(ps, true); 2186 mExpectingBetter.put(ps.name, ps.codePath); 2187 } 2188 2189 continue; 2190 } 2191 2192 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2193 psit.remove(); 2194 logCriticalInfo(Log.WARN, "System package " + ps.name 2195 + " no longer exists; wiping its data"); 2196 removeDataDirsLI(null, ps.name); 2197 } else { 2198 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2199 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2200 possiblyDeletedUpdatedSystemApps.add(ps.name); 2201 } 2202 } 2203 } 2204 } 2205 2206 //look for any incomplete package installations 2207 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2208 //clean up list 2209 for(int i = 0; i < deletePkgsList.size(); i++) { 2210 //clean up here 2211 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2212 } 2213 //delete tmp files 2214 deleteTempPackageFiles(); 2215 2216 // Remove any shared userIDs that have no associated packages 2217 mSettings.pruneSharedUsersLPw(); 2218 2219 if (!mOnlyCore) { 2220 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2221 SystemClock.uptimeMillis()); 2222 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2223 2224 scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2225 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2226 2227 /** 2228 * Remove disable package settings for any updated system 2229 * apps that were removed via an OTA. If they're not a 2230 * previously-updated app, remove them completely. 2231 * Otherwise, just revoke their system-level permissions. 2232 */ 2233 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2234 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2235 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2236 2237 String msg; 2238 if (deletedPkg == null) { 2239 msg = "Updated system package " + deletedAppName 2240 + " no longer exists; wiping its data"; 2241 removeDataDirsLI(null, deletedAppName); 2242 } else { 2243 msg = "Updated system app + " + deletedAppName 2244 + " no longer present; removing system privileges for " 2245 + deletedAppName; 2246 2247 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2248 2249 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2250 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2251 } 2252 logCriticalInfo(Log.WARN, msg); 2253 } 2254 2255 /** 2256 * Make sure all system apps that we expected to appear on 2257 * the userdata partition actually showed up. If they never 2258 * appeared, crawl back and revive the system version. 2259 */ 2260 for (int i = 0; i < mExpectingBetter.size(); i++) { 2261 final String packageName = mExpectingBetter.keyAt(i); 2262 if (!mPackages.containsKey(packageName)) { 2263 final File scanFile = mExpectingBetter.valueAt(i); 2264 2265 logCriticalInfo(Log.WARN, "Expected better " + packageName 2266 + " but never showed up; reverting to system"); 2267 2268 final int reparseFlags; 2269 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2270 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2271 | PackageParser.PARSE_IS_SYSTEM_DIR 2272 | PackageParser.PARSE_IS_PRIVILEGED; 2273 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2274 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2275 | PackageParser.PARSE_IS_SYSTEM_DIR; 2276 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2277 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2278 | PackageParser.PARSE_IS_SYSTEM_DIR; 2279 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2280 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2281 | PackageParser.PARSE_IS_SYSTEM_DIR; 2282 } else { 2283 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2284 continue; 2285 } 2286 2287 mSettings.enableSystemPackageLPw(packageName); 2288 2289 try { 2290 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2291 } catch (PackageManagerException e) { 2292 Slog.e(TAG, "Failed to parse original system package: " 2293 + e.getMessage()); 2294 } 2295 } 2296 } 2297 } 2298 mExpectingBetter.clear(); 2299 2300 // Now that we know all of the shared libraries, update all clients to have 2301 // the correct library paths. 2302 updateAllSharedLibrariesLPw(); 2303 2304 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2305 // NOTE: We ignore potential failures here during a system scan (like 2306 // the rest of the commands above) because there's precious little we 2307 // can do about it. A settings error is reported, though. 2308 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2309 false /* force dexopt */, false /* defer dexopt */, 2310 false /* boot complete */); 2311 } 2312 2313 // Now that we know all the packages we are keeping, 2314 // read and update their last usage times. 2315 mPackageUsage.readLP(); 2316 2317 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2318 SystemClock.uptimeMillis()); 2319 Slog.i(TAG, "Time to scan packages: " 2320 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2321 + " seconds"); 2322 2323 // If the platform SDK has changed since the last time we booted, 2324 // we need to re-grant app permission to catch any new ones that 2325 // appear. This is really a hack, and means that apps can in some 2326 // cases get permissions that the user didn't initially explicitly 2327 // allow... it would be nice to have some better way to handle 2328 // this situation. 2329 int updateFlags = UPDATE_PERMISSIONS_ALL; 2330 if (ver.sdkVersion != mSdkVersion) { 2331 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2332 + mSdkVersion + "; regranting permissions for internal storage"); 2333 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2334 } 2335 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2336 ver.sdkVersion = mSdkVersion; 2337 2338 // If this is the first boot or an update from pre-M, and it is a normal 2339 // boot, then we need to initialize the default preferred apps across 2340 // all defined users. 2341 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { 2342 for (UserInfo user : sUserManager.getUsers(true)) { 2343 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2344 applyFactoryDefaultBrowserLPw(user.id); 2345 primeDomainVerificationsLPw(user.id); 2346 } 2347 } 2348 2349 // If this is first boot after an OTA, and a normal boot, then 2350 // we need to clear code cache directories. 2351 if (mIsUpgrade && !onlyCore) { 2352 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2353 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2354 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2355 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2356 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2357 } 2358 } 2359 ver.fingerprint = Build.FINGERPRINT; 2360 } 2361 2362 checkDefaultBrowser(); 2363 2364 // clear only after permissions and other defaults have been updated 2365 mExistingSystemPackages.clear(); 2366 mPromoteSystemApps = false; 2367 2368 // All the changes are done during package scanning. 2369 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2370 2371 // can downgrade to reader 2372 mSettings.writeLPr(); 2373 2374 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2375 SystemClock.uptimeMillis()); 2376 2377 mRequiredVerifierPackage = getRequiredVerifierLPr(); 2378 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2379 2380 mInstallerService = new PackageInstallerService(context, this); 2381 2382 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2383 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2384 mIntentFilterVerifierComponent); 2385 2386 } // synchronized (mPackages) 2387 } // synchronized (mInstallLock) 2388 2389 // Now after opening every single application zip, make sure they 2390 // are all flushed. Not really needed, but keeps things nice and 2391 // tidy. 2392 Runtime.getRuntime().gc(); 2393 2394 // The initial scanning above does many calls into installd while 2395 // holding the mPackages lock, but we're mostly interested in yelling 2396 // once we have a booted system. 2397 mInstaller.setWarnIfHeld(mPackages); 2398 2399 // Expose private service for system components to use. 2400 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2401 } 2402 2403 @Override 2404 public boolean isFirstBoot() { 2405 return !mRestoredSettings; 2406 } 2407 2408 @Override 2409 public boolean isOnlyCoreApps() { 2410 return mOnlyCore; 2411 } 2412 2413 @Override 2414 public boolean isUpgrade() { 2415 return mIsUpgrade; 2416 } 2417 2418 private String getRequiredVerifierLPr() { 2419 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2420 // We only care about verifier that's installed under system user. 2421 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2422 PackageManager.GET_DISABLED_COMPONENTS, UserHandle.USER_SYSTEM); 2423 2424 String requiredVerifier = null; 2425 2426 final int N = receivers.size(); 2427 for (int i = 0; i < N; i++) { 2428 final ResolveInfo info = receivers.get(i); 2429 2430 if (info.activityInfo == null) { 2431 continue; 2432 } 2433 2434 final String packageName = info.activityInfo.packageName; 2435 2436 if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 2437 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2438 continue; 2439 } 2440 2441 if (requiredVerifier != null) { 2442 throw new RuntimeException("There can be only one required verifier"); 2443 } 2444 2445 requiredVerifier = packageName; 2446 } 2447 2448 return requiredVerifier; 2449 } 2450 2451 private String getRequiredInstallerLPr() { 2452 Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2453 installerIntent.addCategory(Intent.CATEGORY_DEFAULT); 2454 installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2455 2456 final List<ResolveInfo> installers = queryIntentActivities(installerIntent, 2457 PACKAGE_MIME_TYPE, 0, UserHandle.USER_SYSTEM); 2458 2459 String requiredInstaller = null; 2460 2461 final int N = installers.size(); 2462 for (int i = 0; i < N; i++) { 2463 final ResolveInfo info = installers.get(i); 2464 final String packageName = info.activityInfo.packageName; 2465 2466 if (!info.activityInfo.applicationInfo.isSystemApp()) { 2467 continue; 2468 } 2469 2470 if (requiredInstaller != null) { 2471 throw new RuntimeException("There must be one required installer"); 2472 } 2473 2474 requiredInstaller = packageName; 2475 } 2476 2477 if (requiredInstaller == null) { 2478 throw new RuntimeException("There must be one required installer"); 2479 } 2480 2481 return requiredInstaller; 2482 } 2483 2484 private ComponentName getIntentFilterVerifierComponentNameLPr() { 2485 final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2486 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2487 PackageManager.GET_DISABLED_COMPONENTS, UserHandle.USER_SYSTEM); 2488 2489 ComponentName verifierComponentName = null; 2490 2491 int priority = -1000; 2492 final int N = receivers.size(); 2493 for (int i = 0; i < N; i++) { 2494 final ResolveInfo info = receivers.get(i); 2495 2496 if (info.activityInfo == null) { 2497 continue; 2498 } 2499 2500 final String packageName = info.activityInfo.packageName; 2501 2502 final PackageSetting ps = mSettings.mPackages.get(packageName); 2503 if (ps == null) { 2504 continue; 2505 } 2506 2507 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2508 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2509 continue; 2510 } 2511 2512 // Select the IntentFilterVerifier with the highest priority 2513 if (priority < info.priority) { 2514 priority = info.priority; 2515 verifierComponentName = new ComponentName(packageName, info.activityInfo.name); 2516 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Selecting IntentFilterVerifier: " 2517 + verifierComponentName + " with priority: " + info.priority); 2518 } 2519 } 2520 2521 return verifierComponentName; 2522 } 2523 2524 private void primeDomainVerificationsLPw(int userId) { 2525 if (DEBUG_DOMAIN_VERIFICATION) { 2526 Slog.d(TAG, "Priming domain verifications in user " + userId); 2527 } 2528 2529 SystemConfig systemConfig = SystemConfig.getInstance(); 2530 ArraySet<String> packages = systemConfig.getLinkedApps(); 2531 ArraySet<String> domains = new ArraySet<String>(); 2532 2533 for (String packageName : packages) { 2534 PackageParser.Package pkg = mPackages.get(packageName); 2535 if (pkg != null) { 2536 if (!pkg.isSystemApp()) { 2537 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2538 continue; 2539 } 2540 2541 domains.clear(); 2542 for (PackageParser.Activity a : pkg.activities) { 2543 for (ActivityIntentInfo filter : a.intents) { 2544 if (hasValidDomains(filter)) { 2545 domains.addAll(filter.getHostsList()); 2546 } 2547 } 2548 } 2549 2550 if (domains.size() > 0) { 2551 if (DEBUG_DOMAIN_VERIFICATION) { 2552 Slog.v(TAG, " + " + packageName); 2553 } 2554 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2555 // state w.r.t. the formal app-linkage "no verification attempted" state; 2556 // and then 'always' in the per-user state actually used for intent resolution. 2557 final IntentFilterVerificationInfo ivi; 2558 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2559 new ArrayList<String>(domains)); 2560 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2561 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2562 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2563 } else { 2564 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2565 + "' does not handle web links"); 2566 } 2567 } else { 2568 Slog.w(TAG, "Unknown package '" + packageName + "' in sysconfig <app-link>"); 2569 } 2570 } 2571 2572 scheduleWritePackageRestrictionsLocked(userId); 2573 scheduleWriteSettingsLocked(); 2574 } 2575 2576 private void applyFactoryDefaultBrowserLPw(int userId) { 2577 // The default browser app's package name is stored in a string resource, 2578 // with a product-specific overlay used for vendor customization. 2579 String browserPkg = mContext.getResources().getString( 2580 com.android.internal.R.string.default_browser); 2581 if (!TextUtils.isEmpty(browserPkg)) { 2582 // non-empty string => required to be a known package 2583 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2584 if (ps == null) { 2585 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2586 browserPkg = null; 2587 } else { 2588 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2589 } 2590 } 2591 2592 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2593 // default. If there's more than one, just leave everything alone. 2594 if (browserPkg == null) { 2595 calculateDefaultBrowserLPw(userId); 2596 } 2597 } 2598 2599 private void calculateDefaultBrowserLPw(int userId) { 2600 List<String> allBrowsers = resolveAllBrowserApps(userId); 2601 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2602 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2603 } 2604 2605 private List<String> resolveAllBrowserApps(int userId) { 2606 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2607 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2608 PackageManager.MATCH_ALL, userId); 2609 2610 final int count = list.size(); 2611 List<String> result = new ArrayList<String>(count); 2612 for (int i=0; i<count; i++) { 2613 ResolveInfo info = list.get(i); 2614 if (info.activityInfo == null 2615 || !info.handleAllWebDataURI 2616 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2617 || result.contains(info.activityInfo.packageName)) { 2618 continue; 2619 } 2620 result.add(info.activityInfo.packageName); 2621 } 2622 2623 return result; 2624 } 2625 2626 private boolean packageIsBrowser(String packageName, int userId) { 2627 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2628 PackageManager.MATCH_ALL, userId); 2629 final int N = list.size(); 2630 for (int i = 0; i < N; i++) { 2631 ResolveInfo info = list.get(i); 2632 if (packageName.equals(info.activityInfo.packageName)) { 2633 return true; 2634 } 2635 } 2636 return false; 2637 } 2638 2639 private void checkDefaultBrowser() { 2640 final int myUserId = UserHandle.myUserId(); 2641 final String packageName = getDefaultBrowserPackageName(myUserId); 2642 if (packageName != null) { 2643 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2644 if (info == null) { 2645 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2646 synchronized (mPackages) { 2647 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2648 } 2649 } 2650 } 2651 } 2652 2653 @Override 2654 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2655 throws RemoteException { 2656 try { 2657 return super.onTransact(code, data, reply, flags); 2658 } catch (RuntimeException e) { 2659 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2660 Slog.wtf(TAG, "Package Manager Crash", e); 2661 } 2662 throw e; 2663 } 2664 } 2665 2666 void cleanupInstallFailedPackage(PackageSetting ps) { 2667 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2668 2669 removeDataDirsLI(ps.volumeUuid, ps.name); 2670 if (ps.codePath != null) { 2671 if (ps.codePath.isDirectory()) { 2672 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath()); 2673 } else { 2674 ps.codePath.delete(); 2675 } 2676 } 2677 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2678 if (ps.resourcePath.isDirectory()) { 2679 FileUtils.deleteContents(ps.resourcePath); 2680 } 2681 ps.resourcePath.delete(); 2682 } 2683 mSettings.removePackageLPw(ps.name); 2684 } 2685 2686 static int[] appendInts(int[] cur, int[] add) { 2687 if (add == null) return cur; 2688 if (cur == null) return add; 2689 final int N = add.length; 2690 for (int i=0; i<N; i++) { 2691 cur = appendInt(cur, add[i]); 2692 } 2693 return cur; 2694 } 2695 2696 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2697 if (!sUserManager.exists(userId)) return null; 2698 final PackageSetting ps = (PackageSetting) p.mExtras; 2699 if (ps == null) { 2700 return null; 2701 } 2702 2703 final PermissionsState permissionsState = ps.getPermissionsState(); 2704 2705 final int[] gids = permissionsState.computeGids(userId); 2706 final Set<String> permissions = permissionsState.getPermissions(userId); 2707 final PackageUserState state = ps.readUserState(userId); 2708 2709 return PackageParser.generatePackageInfo(p, gids, flags, 2710 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2711 } 2712 2713 @Override 2714 public boolean isPackageFrozen(String packageName) { 2715 synchronized (mPackages) { 2716 final PackageSetting ps = mSettings.mPackages.get(packageName); 2717 if (ps != null) { 2718 return ps.frozen; 2719 } 2720 } 2721 Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen"); 2722 return true; 2723 } 2724 2725 @Override 2726 public boolean isPackageAvailable(String packageName, int userId) { 2727 if (!sUserManager.exists(userId)) return false; 2728 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 2729 synchronized (mPackages) { 2730 PackageParser.Package p = mPackages.get(packageName); 2731 if (p != null) { 2732 final PackageSetting ps = (PackageSetting) p.mExtras; 2733 if (ps != null) { 2734 final PackageUserState state = ps.readUserState(userId); 2735 if (state != null) { 2736 return PackageParser.isAvailable(state); 2737 } 2738 } 2739 } 2740 } 2741 return false; 2742 } 2743 2744 @Override 2745 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2746 if (!sUserManager.exists(userId)) return null; 2747 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 2748 // reader 2749 synchronized (mPackages) { 2750 PackageParser.Package p = mPackages.get(packageName); 2751 if (DEBUG_PACKAGE_INFO) 2752 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2753 if (p != null) { 2754 return generatePackageInfo(p, flags, userId); 2755 } 2756 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2757 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2758 } 2759 } 2760 return null; 2761 } 2762 2763 @Override 2764 public String[] currentToCanonicalPackageNames(String[] names) { 2765 String[] out = new String[names.length]; 2766 // reader 2767 synchronized (mPackages) { 2768 for (int i=names.length-1; i>=0; i--) { 2769 PackageSetting ps = mSettings.mPackages.get(names[i]); 2770 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2771 } 2772 } 2773 return out; 2774 } 2775 2776 @Override 2777 public String[] canonicalToCurrentPackageNames(String[] names) { 2778 String[] out = new String[names.length]; 2779 // reader 2780 synchronized (mPackages) { 2781 for (int i=names.length-1; i>=0; i--) { 2782 String cur = mSettings.mRenamedPackages.get(names[i]); 2783 out[i] = cur != null ? cur : names[i]; 2784 } 2785 } 2786 return out; 2787 } 2788 2789 @Override 2790 public int getPackageUid(String packageName, int userId) { 2791 return getPackageUidEtc(packageName, 0, userId); 2792 } 2793 2794 @Override 2795 public int getPackageUidEtc(String packageName, int flags, int userId) { 2796 if (!sUserManager.exists(userId)) return -1; 2797 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 2798 2799 // reader 2800 synchronized (mPackages) { 2801 final PackageParser.Package p = mPackages.get(packageName); 2802 if (p != null) { 2803 return UserHandle.getUid(userId, p.applicationInfo.uid); 2804 } 2805 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2806 final PackageSetting ps = mSettings.mPackages.get(packageName); 2807 if (ps != null) { 2808 return UserHandle.getUid(userId, ps.appId); 2809 } 2810 } 2811 } 2812 2813 return -1; 2814 } 2815 2816 @Override 2817 public int[] getPackageGids(String packageName, int userId) { 2818 return getPackageGidsEtc(packageName, 0, userId); 2819 } 2820 2821 @Override 2822 public int[] getPackageGidsEtc(String packageName, int flags, int userId) { 2823 if (!sUserManager.exists(userId)) { 2824 return null; 2825 } 2826 2827 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 2828 "getPackageGids"); 2829 2830 // reader 2831 synchronized (mPackages) { 2832 final PackageParser.Package p = mPackages.get(packageName); 2833 if (p != null) { 2834 PackageSetting ps = (PackageSetting) p.mExtras; 2835 return ps.getPermissionsState().computeGids(userId); 2836 } 2837 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2838 final PackageSetting ps = mSettings.mPackages.get(packageName); 2839 if (ps != null) { 2840 return ps.getPermissionsState().computeGids(userId); 2841 } 2842 } 2843 } 2844 2845 return null; 2846 } 2847 2848 static PermissionInfo generatePermissionInfo( 2849 BasePermission bp, int flags) { 2850 if (bp.perm != null) { 2851 return PackageParser.generatePermissionInfo(bp.perm, flags); 2852 } 2853 PermissionInfo pi = new PermissionInfo(); 2854 pi.name = bp.name; 2855 pi.packageName = bp.sourcePackage; 2856 pi.nonLocalizedLabel = bp.name; 2857 pi.protectionLevel = bp.protectionLevel; 2858 return pi; 2859 } 2860 2861 @Override 2862 public PermissionInfo getPermissionInfo(String name, int flags) { 2863 // reader 2864 synchronized (mPackages) { 2865 final BasePermission p = mSettings.mPermissions.get(name); 2866 if (p != null) { 2867 return generatePermissionInfo(p, flags); 2868 } 2869 return null; 2870 } 2871 } 2872 2873 @Override 2874 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2875 // reader 2876 synchronized (mPackages) { 2877 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2878 for (BasePermission p : mSettings.mPermissions.values()) { 2879 if (group == null) { 2880 if (p.perm == null || p.perm.info.group == null) { 2881 out.add(generatePermissionInfo(p, flags)); 2882 } 2883 } else { 2884 if (p.perm != null && group.equals(p.perm.info.group)) { 2885 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2886 } 2887 } 2888 } 2889 2890 if (out.size() > 0) { 2891 return out; 2892 } 2893 return mPermissionGroups.containsKey(group) ? out : null; 2894 } 2895 } 2896 2897 @Override 2898 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2899 // reader 2900 synchronized (mPackages) { 2901 return PackageParser.generatePermissionGroupInfo( 2902 mPermissionGroups.get(name), flags); 2903 } 2904 } 2905 2906 @Override 2907 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2908 // reader 2909 synchronized (mPackages) { 2910 final int N = mPermissionGroups.size(); 2911 ArrayList<PermissionGroupInfo> out 2912 = new ArrayList<PermissionGroupInfo>(N); 2913 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2914 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2915 } 2916 return out; 2917 } 2918 } 2919 2920 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2921 int userId) { 2922 if (!sUserManager.exists(userId)) return null; 2923 PackageSetting ps = mSettings.mPackages.get(packageName); 2924 if (ps != null) { 2925 if (ps.pkg == null) { 2926 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2927 flags, userId); 2928 if (pInfo != null) { 2929 return pInfo.applicationInfo; 2930 } 2931 return null; 2932 } 2933 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2934 ps.readUserState(userId), userId); 2935 } 2936 return null; 2937 } 2938 2939 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2940 int userId) { 2941 if (!sUserManager.exists(userId)) return null; 2942 PackageSetting ps = mSettings.mPackages.get(packageName); 2943 if (ps != null) { 2944 PackageParser.Package pkg = ps.pkg; 2945 if (pkg == null) { 2946 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2947 return null; 2948 } 2949 // Only data remains, so we aren't worried about code paths 2950 pkg = new PackageParser.Package(packageName); 2951 pkg.applicationInfo.packageName = packageName; 2952 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2953 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 2954 pkg.applicationInfo.dataDir = Environment 2955 .getDataUserPackageDirectory(ps.volumeUuid, userId, packageName) 2956 .getAbsolutePath(); 2957 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2958 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2959 } 2960 return generatePackageInfo(pkg, flags, userId); 2961 } 2962 return null; 2963 } 2964 2965 @Override 2966 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2967 if (!sUserManager.exists(userId)) return null; 2968 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2969 // writer 2970 synchronized (mPackages) { 2971 PackageParser.Package p = mPackages.get(packageName); 2972 if (DEBUG_PACKAGE_INFO) Log.v( 2973 TAG, "getApplicationInfo " + packageName 2974 + ": " + p); 2975 if (p != null) { 2976 PackageSetting ps = mSettings.mPackages.get(packageName); 2977 if (ps == null) return null; 2978 // Note: isEnabledLP() does not apply here - always return info 2979 return PackageParser.generateApplicationInfo( 2980 p, flags, ps.readUserState(userId), userId); 2981 } 2982 if ("android".equals(packageName)||"system".equals(packageName)) { 2983 return mAndroidApplication; 2984 } 2985 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2986 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2987 } 2988 } 2989 return null; 2990 } 2991 2992 @Override 2993 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 2994 final IPackageDataObserver observer) { 2995 mContext.enforceCallingOrSelfPermission( 2996 android.Manifest.permission.CLEAR_APP_CACHE, null); 2997 // Queue up an async operation since clearing cache may take a little while. 2998 mHandler.post(new Runnable() { 2999 public void run() { 3000 mHandler.removeCallbacks(this); 3001 int retCode = -1; 3002 synchronized (mInstallLock) { 3003 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 3004 if (retCode < 0) { 3005 Slog.w(TAG, "Couldn't clear application caches"); 3006 } 3007 } 3008 if (observer != null) { 3009 try { 3010 observer.onRemoveCompleted(null, (retCode >= 0)); 3011 } catch (RemoteException e) { 3012 Slog.w(TAG, "RemoveException when invoking call back"); 3013 } 3014 } 3015 } 3016 }); 3017 } 3018 3019 @Override 3020 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3021 final IntentSender pi) { 3022 mContext.enforceCallingOrSelfPermission( 3023 android.Manifest.permission.CLEAR_APP_CACHE, null); 3024 // Queue up an async operation since clearing cache may take a little while. 3025 mHandler.post(new Runnable() { 3026 public void run() { 3027 mHandler.removeCallbacks(this); 3028 int retCode = -1; 3029 synchronized (mInstallLock) { 3030 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 3031 if (retCode < 0) { 3032 Slog.w(TAG, "Couldn't clear application caches"); 3033 } 3034 } 3035 if(pi != null) { 3036 try { 3037 // Callback via pending intent 3038 int code = (retCode >= 0) ? 1 : 0; 3039 pi.sendIntent(null, code, null, 3040 null, null); 3041 } catch (SendIntentException e1) { 3042 Slog.i(TAG, "Failed to send pending intent"); 3043 } 3044 } 3045 } 3046 }); 3047 } 3048 3049 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3050 synchronized (mInstallLock) { 3051 if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) { 3052 throw new IOException("Failed to free enough space"); 3053 } 3054 } 3055 } 3056 3057 @Override 3058 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3059 if (!sUserManager.exists(userId)) return null; 3060 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 3061 synchronized (mPackages) { 3062 PackageParser.Activity a = mActivities.mActivities.get(component); 3063 3064 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3065 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 3066 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3067 if (ps == null) return null; 3068 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3069 userId); 3070 } 3071 if (mResolveComponentName.equals(component)) { 3072 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3073 new PackageUserState(), userId); 3074 } 3075 } 3076 return null; 3077 } 3078 3079 @Override 3080 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3081 String resolvedType) { 3082 synchronized (mPackages) { 3083 if (component.equals(mResolveComponentName)) { 3084 // The resolver supports EVERYTHING! 3085 return true; 3086 } 3087 PackageParser.Activity a = mActivities.mActivities.get(component); 3088 if (a == null) { 3089 return false; 3090 } 3091 for (int i=0; i<a.intents.size(); i++) { 3092 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3093 intent.getData(), intent.getCategories(), TAG) >= 0) { 3094 return true; 3095 } 3096 } 3097 return false; 3098 } 3099 } 3100 3101 @Override 3102 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3103 if (!sUserManager.exists(userId)) return null; 3104 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 3105 synchronized (mPackages) { 3106 PackageParser.Activity a = mReceivers.mActivities.get(component); 3107 if (DEBUG_PACKAGE_INFO) Log.v( 3108 TAG, "getReceiverInfo " + component + ": " + a); 3109 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 3110 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3111 if (ps == null) return null; 3112 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3113 userId); 3114 } 3115 } 3116 return null; 3117 } 3118 3119 @Override 3120 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3121 if (!sUserManager.exists(userId)) return null; 3122 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 3123 synchronized (mPackages) { 3124 PackageParser.Service s = mServices.mServices.get(component); 3125 if (DEBUG_PACKAGE_INFO) Log.v( 3126 TAG, "getServiceInfo " + component + ": " + s); 3127 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 3128 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3129 if (ps == null) return null; 3130 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3131 userId); 3132 } 3133 } 3134 return null; 3135 } 3136 3137 @Override 3138 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3139 if (!sUserManager.exists(userId)) return null; 3140 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 3141 synchronized (mPackages) { 3142 PackageParser.Provider p = mProviders.mProviders.get(component); 3143 if (DEBUG_PACKAGE_INFO) Log.v( 3144 TAG, "getProviderInfo " + component + ": " + p); 3145 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 3146 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3147 if (ps == null) return null; 3148 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3149 userId); 3150 } 3151 } 3152 return null; 3153 } 3154 3155 @Override 3156 public String[] getSystemSharedLibraryNames() { 3157 Set<String> libSet; 3158 synchronized (mPackages) { 3159 libSet = mSharedLibraries.keySet(); 3160 int size = libSet.size(); 3161 if (size > 0) { 3162 String[] libs = new String[size]; 3163 libSet.toArray(libs); 3164 return libs; 3165 } 3166 } 3167 return null; 3168 } 3169 3170 /** 3171 * @hide 3172 */ 3173 PackageParser.Package findSharedNonSystemLibrary(String libName) { 3174 synchronized (mPackages) { 3175 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 3176 if (lib != null && lib.apk != null) { 3177 return mPackages.get(lib.apk); 3178 } 3179 } 3180 return null; 3181 } 3182 3183 @Override 3184 public FeatureInfo[] getSystemAvailableFeatures() { 3185 Collection<FeatureInfo> featSet; 3186 synchronized (mPackages) { 3187 featSet = mAvailableFeatures.values(); 3188 int size = featSet.size(); 3189 if (size > 0) { 3190 FeatureInfo[] features = new FeatureInfo[size+1]; 3191 featSet.toArray(features); 3192 FeatureInfo fi = new FeatureInfo(); 3193 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3194 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3195 features[size] = fi; 3196 return features; 3197 } 3198 } 3199 return null; 3200 } 3201 3202 @Override 3203 public boolean hasSystemFeature(String name) { 3204 synchronized (mPackages) { 3205 return mAvailableFeatures.containsKey(name); 3206 } 3207 } 3208 3209 private void checkValidCaller(int uid, int userId) { 3210 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 3211 return; 3212 3213 throw new SecurityException("Caller uid=" + uid 3214 + " is not privileged to communicate with user=" + userId); 3215 } 3216 3217 @Override 3218 public int checkPermission(String permName, String pkgName, int userId) { 3219 if (!sUserManager.exists(userId)) { 3220 return PackageManager.PERMISSION_DENIED; 3221 } 3222 3223 synchronized (mPackages) { 3224 final PackageParser.Package p = mPackages.get(pkgName); 3225 if (p != null && p.mExtras != null) { 3226 final PackageSetting ps = (PackageSetting) p.mExtras; 3227 final PermissionsState permissionsState = ps.getPermissionsState(); 3228 if (permissionsState.hasPermission(permName, userId)) { 3229 return PackageManager.PERMISSION_GRANTED; 3230 } 3231 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3232 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3233 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3234 return PackageManager.PERMISSION_GRANTED; 3235 } 3236 } 3237 } 3238 3239 return PackageManager.PERMISSION_DENIED; 3240 } 3241 3242 @Override 3243 public int checkUidPermission(String permName, int uid) { 3244 final int userId = UserHandle.getUserId(uid); 3245 3246 if (!sUserManager.exists(userId)) { 3247 return PackageManager.PERMISSION_DENIED; 3248 } 3249 3250 synchronized (mPackages) { 3251 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3252 if (obj != null) { 3253 final SettingBase ps = (SettingBase) obj; 3254 final PermissionsState permissionsState = ps.getPermissionsState(); 3255 if (permissionsState.hasPermission(permName, userId)) { 3256 return PackageManager.PERMISSION_GRANTED; 3257 } 3258 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3259 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3260 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3261 return PackageManager.PERMISSION_GRANTED; 3262 } 3263 } else { 3264 ArraySet<String> perms = mSystemPermissions.get(uid); 3265 if (perms != null) { 3266 if (perms.contains(permName)) { 3267 return PackageManager.PERMISSION_GRANTED; 3268 } 3269 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3270 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3271 return PackageManager.PERMISSION_GRANTED; 3272 } 3273 } 3274 } 3275 } 3276 3277 return PackageManager.PERMISSION_DENIED; 3278 } 3279 3280 @Override 3281 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3282 if (UserHandle.getCallingUserId() != userId) { 3283 mContext.enforceCallingPermission( 3284 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3285 "isPermissionRevokedByPolicy for user " + userId); 3286 } 3287 3288 if (checkPermission(permission, packageName, userId) 3289 == PackageManager.PERMISSION_GRANTED) { 3290 return false; 3291 } 3292 3293 final long identity = Binder.clearCallingIdentity(); 3294 try { 3295 final int flags = getPermissionFlags(permission, packageName, userId); 3296 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3297 } finally { 3298 Binder.restoreCallingIdentity(identity); 3299 } 3300 } 3301 3302 @Override 3303 public String getPermissionControllerPackageName() { 3304 synchronized (mPackages) { 3305 return mRequiredInstallerPackage; 3306 } 3307 } 3308 3309 /** 3310 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3311 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3312 * @param checkShell TODO(yamasani): 3313 * @param message the message to log on security exception 3314 */ 3315 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3316 boolean checkShell, String message) { 3317 if (userId < 0) { 3318 throw new IllegalArgumentException("Invalid userId " + userId); 3319 } 3320 if (checkShell) { 3321 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3322 } 3323 if (userId == UserHandle.getUserId(callingUid)) return; 3324 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3325 if (requireFullPermission) { 3326 mContext.enforceCallingOrSelfPermission( 3327 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3328 } else { 3329 try { 3330 mContext.enforceCallingOrSelfPermission( 3331 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3332 } catch (SecurityException se) { 3333 mContext.enforceCallingOrSelfPermission( 3334 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3335 } 3336 } 3337 } 3338 } 3339 3340 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3341 if (callingUid == Process.SHELL_UID) { 3342 if (userHandle >= 0 3343 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3344 throw new SecurityException("Shell does not have permission to access user " 3345 + userHandle); 3346 } else if (userHandle < 0) { 3347 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3348 + Debug.getCallers(3)); 3349 } 3350 } 3351 } 3352 3353 private BasePermission findPermissionTreeLP(String permName) { 3354 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3355 if (permName.startsWith(bp.name) && 3356 permName.length() > bp.name.length() && 3357 permName.charAt(bp.name.length()) == '.') { 3358 return bp; 3359 } 3360 } 3361 return null; 3362 } 3363 3364 private BasePermission checkPermissionTreeLP(String permName) { 3365 if (permName != null) { 3366 BasePermission bp = findPermissionTreeLP(permName); 3367 if (bp != null) { 3368 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3369 return bp; 3370 } 3371 throw new SecurityException("Calling uid " 3372 + Binder.getCallingUid() 3373 + " is not allowed to add to permission tree " 3374 + bp.name + " owned by uid " + bp.uid); 3375 } 3376 } 3377 throw new SecurityException("No permission tree found for " + permName); 3378 } 3379 3380 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3381 if (s1 == null) { 3382 return s2 == null; 3383 } 3384 if (s2 == null) { 3385 return false; 3386 } 3387 if (s1.getClass() != s2.getClass()) { 3388 return false; 3389 } 3390 return s1.equals(s2); 3391 } 3392 3393 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3394 if (pi1.icon != pi2.icon) return false; 3395 if (pi1.logo != pi2.logo) return false; 3396 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3397 if (!compareStrings(pi1.name, pi2.name)) return false; 3398 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3399 // We'll take care of setting this one. 3400 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3401 // These are not currently stored in settings. 3402 //if (!compareStrings(pi1.group, pi2.group)) return false; 3403 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3404 //if (pi1.labelRes != pi2.labelRes) return false; 3405 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3406 return true; 3407 } 3408 3409 int permissionInfoFootprint(PermissionInfo info) { 3410 int size = info.name.length(); 3411 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3412 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3413 return size; 3414 } 3415 3416 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3417 int size = 0; 3418 for (BasePermission perm : mSettings.mPermissions.values()) { 3419 if (perm.uid == tree.uid) { 3420 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3421 } 3422 } 3423 return size; 3424 } 3425 3426 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3427 // We calculate the max size of permissions defined by this uid and throw 3428 // if that plus the size of 'info' would exceed our stated maximum. 3429 if (tree.uid != Process.SYSTEM_UID) { 3430 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3431 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3432 throw new SecurityException("Permission tree size cap exceeded"); 3433 } 3434 } 3435 } 3436 3437 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3438 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3439 throw new SecurityException("Label must be specified in permission"); 3440 } 3441 BasePermission tree = checkPermissionTreeLP(info.name); 3442 BasePermission bp = mSettings.mPermissions.get(info.name); 3443 boolean added = bp == null; 3444 boolean changed = true; 3445 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3446 if (added) { 3447 enforcePermissionCapLocked(info, tree); 3448 bp = new BasePermission(info.name, tree.sourcePackage, 3449 BasePermission.TYPE_DYNAMIC); 3450 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3451 throw new SecurityException( 3452 "Not allowed to modify non-dynamic permission " 3453 + info.name); 3454 } else { 3455 if (bp.protectionLevel == fixedLevel 3456 && bp.perm.owner.equals(tree.perm.owner) 3457 && bp.uid == tree.uid 3458 && comparePermissionInfos(bp.perm.info, info)) { 3459 changed = false; 3460 } 3461 } 3462 bp.protectionLevel = fixedLevel; 3463 info = new PermissionInfo(info); 3464 info.protectionLevel = fixedLevel; 3465 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3466 bp.perm.info.packageName = tree.perm.info.packageName; 3467 bp.uid = tree.uid; 3468 if (added) { 3469 mSettings.mPermissions.put(info.name, bp); 3470 } 3471 if (changed) { 3472 if (!async) { 3473 mSettings.writeLPr(); 3474 } else { 3475 scheduleWriteSettingsLocked(); 3476 } 3477 } 3478 return added; 3479 } 3480 3481 @Override 3482 public boolean addPermission(PermissionInfo info) { 3483 synchronized (mPackages) { 3484 return addPermissionLocked(info, false); 3485 } 3486 } 3487 3488 @Override 3489 public boolean addPermissionAsync(PermissionInfo info) { 3490 synchronized (mPackages) { 3491 return addPermissionLocked(info, true); 3492 } 3493 } 3494 3495 @Override 3496 public void removePermission(String name) { 3497 synchronized (mPackages) { 3498 checkPermissionTreeLP(name); 3499 BasePermission bp = mSettings.mPermissions.get(name); 3500 if (bp != null) { 3501 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3502 throw new SecurityException( 3503 "Not allowed to modify non-dynamic permission " 3504 + name); 3505 } 3506 mSettings.mPermissions.remove(name); 3507 mSettings.writeLPr(); 3508 } 3509 } 3510 } 3511 3512 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3513 BasePermission bp) { 3514 int index = pkg.requestedPermissions.indexOf(bp.name); 3515 if (index == -1) { 3516 throw new SecurityException("Package " + pkg.packageName 3517 + " has not requested permission " + bp.name); 3518 } 3519 if (!bp.isRuntime() && !bp.isDevelopment()) { 3520 throw new SecurityException("Permission " + bp.name 3521 + " is not a changeable permission type"); 3522 } 3523 } 3524 3525 @Override 3526 public void grantRuntimePermission(String packageName, String name, final int userId) { 3527 if (!sUserManager.exists(userId)) { 3528 Log.e(TAG, "No such user:" + userId); 3529 return; 3530 } 3531 3532 mContext.enforceCallingOrSelfPermission( 3533 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3534 "grantRuntimePermission"); 3535 3536 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3537 "grantRuntimePermission"); 3538 3539 final int uid; 3540 final SettingBase sb; 3541 3542 synchronized (mPackages) { 3543 final PackageParser.Package pkg = mPackages.get(packageName); 3544 if (pkg == null) { 3545 throw new IllegalArgumentException("Unknown package: " + packageName); 3546 } 3547 3548 final BasePermission bp = mSettings.mPermissions.get(name); 3549 if (bp == null) { 3550 throw new IllegalArgumentException("Unknown permission: " + name); 3551 } 3552 3553 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3554 3555 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3556 sb = (SettingBase) pkg.mExtras; 3557 if (sb == null) { 3558 throw new IllegalArgumentException("Unknown package: " + packageName); 3559 } 3560 3561 final PermissionsState permissionsState = sb.getPermissionsState(); 3562 3563 final int flags = permissionsState.getPermissionFlags(name, userId); 3564 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3565 throw new SecurityException("Cannot grant system fixed permission: " 3566 + name + " for package: " + packageName); 3567 } 3568 3569 if (bp.isDevelopment()) { 3570 // Development permissions must be handled specially, since they are not 3571 // normal runtime permissions. For now they apply to all users. 3572 if (permissionsState.grantInstallPermission(bp) != 3573 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3574 scheduleWriteSettingsLocked(); 3575 } 3576 return; 3577 } 3578 3579 final int result = permissionsState.grantRuntimePermission(bp, userId); 3580 switch (result) { 3581 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3582 return; 3583 } 3584 3585 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3586 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3587 mHandler.post(new Runnable() { 3588 @Override 3589 public void run() { 3590 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 3591 } 3592 }); 3593 } 3594 break; 3595 } 3596 3597 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3598 3599 // Not critical if that is lost - app has to request again. 3600 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3601 } 3602 3603 // Only need to do this if user is initialized. Otherwise it's a new user 3604 // and there are no processes running as the user yet and there's no need 3605 // to make an expensive call to remount processes for the changed permissions. 3606 if (READ_EXTERNAL_STORAGE.equals(name) 3607 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3608 final long token = Binder.clearCallingIdentity(); 3609 try { 3610 if (sUserManager.isInitialized(userId)) { 3611 MountServiceInternal mountServiceInternal = LocalServices.getService( 3612 MountServiceInternal.class); 3613 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3614 } 3615 } finally { 3616 Binder.restoreCallingIdentity(token); 3617 } 3618 } 3619 } 3620 3621 @Override 3622 public void revokeRuntimePermission(String packageName, String name, int userId) { 3623 if (!sUserManager.exists(userId)) { 3624 Log.e(TAG, "No such user:" + userId); 3625 return; 3626 } 3627 3628 mContext.enforceCallingOrSelfPermission( 3629 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3630 "revokeRuntimePermission"); 3631 3632 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3633 "revokeRuntimePermission"); 3634 3635 final int appId; 3636 3637 synchronized (mPackages) { 3638 final PackageParser.Package pkg = mPackages.get(packageName); 3639 if (pkg == null) { 3640 throw new IllegalArgumentException("Unknown package: " + packageName); 3641 } 3642 3643 final BasePermission bp = mSettings.mPermissions.get(name); 3644 if (bp == null) { 3645 throw new IllegalArgumentException("Unknown permission: " + name); 3646 } 3647 3648 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3649 3650 SettingBase sb = (SettingBase) pkg.mExtras; 3651 if (sb == null) { 3652 throw new IllegalArgumentException("Unknown package: " + packageName); 3653 } 3654 3655 final PermissionsState permissionsState = sb.getPermissionsState(); 3656 3657 final int flags = permissionsState.getPermissionFlags(name, userId); 3658 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3659 throw new SecurityException("Cannot revoke system fixed permission: " 3660 + name + " for package: " + packageName); 3661 } 3662 3663 if (bp.isDevelopment()) { 3664 // Development permissions must be handled specially, since they are not 3665 // normal runtime permissions. For now they apply to all users. 3666 if (permissionsState.revokeInstallPermission(bp) != 3667 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3668 scheduleWriteSettingsLocked(); 3669 } 3670 return; 3671 } 3672 3673 if (permissionsState.revokeRuntimePermission(bp, userId) == 3674 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3675 return; 3676 } 3677 3678 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 3679 3680 // Critical, after this call app should never have the permission. 3681 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3682 3683 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3684 } 3685 3686 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 3687 } 3688 3689 @Override 3690 public void resetRuntimePermissions() { 3691 mContext.enforceCallingOrSelfPermission( 3692 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3693 "revokeRuntimePermission"); 3694 3695 int callingUid = Binder.getCallingUid(); 3696 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3697 mContext.enforceCallingOrSelfPermission( 3698 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3699 "resetRuntimePermissions"); 3700 } 3701 3702 synchronized (mPackages) { 3703 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 3704 for (int userId : UserManagerService.getInstance().getUserIds()) { 3705 final int packageCount = mPackages.size(); 3706 for (int i = 0; i < packageCount; i++) { 3707 PackageParser.Package pkg = mPackages.valueAt(i); 3708 if (!(pkg.mExtras instanceof PackageSetting)) { 3709 continue; 3710 } 3711 PackageSetting ps = (PackageSetting) pkg.mExtras; 3712 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 3713 } 3714 } 3715 } 3716 } 3717 3718 @Override 3719 public int getPermissionFlags(String name, String packageName, int userId) { 3720 if (!sUserManager.exists(userId)) { 3721 return 0; 3722 } 3723 3724 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 3725 3726 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3727 "getPermissionFlags"); 3728 3729 synchronized (mPackages) { 3730 final PackageParser.Package pkg = mPackages.get(packageName); 3731 if (pkg == null) { 3732 throw new IllegalArgumentException("Unknown package: " + packageName); 3733 } 3734 3735 final BasePermission bp = mSettings.mPermissions.get(name); 3736 if (bp == null) { 3737 throw new IllegalArgumentException("Unknown permission: " + name); 3738 } 3739 3740 SettingBase sb = (SettingBase) pkg.mExtras; 3741 if (sb == null) { 3742 throw new IllegalArgumentException("Unknown package: " + packageName); 3743 } 3744 3745 PermissionsState permissionsState = sb.getPermissionsState(); 3746 return permissionsState.getPermissionFlags(name, userId); 3747 } 3748 } 3749 3750 @Override 3751 public void updatePermissionFlags(String name, String packageName, int flagMask, 3752 int flagValues, int userId) { 3753 if (!sUserManager.exists(userId)) { 3754 return; 3755 } 3756 3757 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 3758 3759 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3760 "updatePermissionFlags"); 3761 3762 // Only the system can change these flags and nothing else. 3763 if (getCallingUid() != Process.SYSTEM_UID) { 3764 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3765 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3766 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 3767 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 3768 } 3769 3770 synchronized (mPackages) { 3771 final PackageParser.Package pkg = mPackages.get(packageName); 3772 if (pkg == null) { 3773 throw new IllegalArgumentException("Unknown package: " + packageName); 3774 } 3775 3776 final BasePermission bp = mSettings.mPermissions.get(name); 3777 if (bp == null) { 3778 throw new IllegalArgumentException("Unknown permission: " + name); 3779 } 3780 3781 SettingBase sb = (SettingBase) pkg.mExtras; 3782 if (sb == null) { 3783 throw new IllegalArgumentException("Unknown package: " + packageName); 3784 } 3785 3786 PermissionsState permissionsState = sb.getPermissionsState(); 3787 3788 // Only the package manager can change flags for system component permissions. 3789 final int flags = permissionsState.getPermissionFlags(bp.name, userId); 3790 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3791 return; 3792 } 3793 3794 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 3795 3796 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 3797 // Install and runtime permissions are stored in different places, 3798 // so figure out what permission changed and persist the change. 3799 if (permissionsState.getInstallPermissionState(name) != null) { 3800 scheduleWriteSettingsLocked(); 3801 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 3802 || hadState) { 3803 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3804 } 3805 } 3806 } 3807 } 3808 3809 /** 3810 * Update the permission flags for all packages and runtime permissions of a user in order 3811 * to allow device or profile owner to remove POLICY_FIXED. 3812 */ 3813 @Override 3814 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 3815 if (!sUserManager.exists(userId)) { 3816 return; 3817 } 3818 3819 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 3820 3821 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3822 "updatePermissionFlagsForAllApps"); 3823 3824 // Only the system can change system fixed flags. 3825 if (getCallingUid() != Process.SYSTEM_UID) { 3826 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3827 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3828 } 3829 3830 synchronized (mPackages) { 3831 boolean changed = false; 3832 final int packageCount = mPackages.size(); 3833 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 3834 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 3835 SettingBase sb = (SettingBase) pkg.mExtras; 3836 if (sb == null) { 3837 continue; 3838 } 3839 PermissionsState permissionsState = sb.getPermissionsState(); 3840 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 3841 userId, flagMask, flagValues); 3842 } 3843 if (changed) { 3844 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3845 } 3846 } 3847 } 3848 3849 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 3850 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 3851 != PackageManager.PERMISSION_GRANTED 3852 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 3853 != PackageManager.PERMISSION_GRANTED) { 3854 throw new SecurityException(message + " requires " 3855 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 3856 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 3857 } 3858 } 3859 3860 @Override 3861 public boolean shouldShowRequestPermissionRationale(String permissionName, 3862 String packageName, int userId) { 3863 if (UserHandle.getCallingUserId() != userId) { 3864 mContext.enforceCallingPermission( 3865 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3866 "canShowRequestPermissionRationale for user " + userId); 3867 } 3868 3869 final int uid = getPackageUid(packageName, userId); 3870 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 3871 return false; 3872 } 3873 3874 if (checkPermission(permissionName, packageName, userId) 3875 == PackageManager.PERMISSION_GRANTED) { 3876 return false; 3877 } 3878 3879 final int flags; 3880 3881 final long identity = Binder.clearCallingIdentity(); 3882 try { 3883 flags = getPermissionFlags(permissionName, 3884 packageName, userId); 3885 } finally { 3886 Binder.restoreCallingIdentity(identity); 3887 } 3888 3889 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 3890 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 3891 | PackageManager.FLAG_PERMISSION_USER_FIXED; 3892 3893 if ((flags & fixedFlags) != 0) { 3894 return false; 3895 } 3896 3897 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 3898 } 3899 3900 @Override 3901 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3902 mContext.enforceCallingOrSelfPermission( 3903 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 3904 "addOnPermissionsChangeListener"); 3905 3906 synchronized (mPackages) { 3907 mOnPermissionChangeListeners.addListenerLocked(listener); 3908 } 3909 } 3910 3911 @Override 3912 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3913 synchronized (mPackages) { 3914 mOnPermissionChangeListeners.removeListenerLocked(listener); 3915 } 3916 } 3917 3918 @Override 3919 public boolean isProtectedBroadcast(String actionName) { 3920 synchronized (mPackages) { 3921 return mProtectedBroadcasts.contains(actionName); 3922 } 3923 } 3924 3925 @Override 3926 public int checkSignatures(String pkg1, String pkg2) { 3927 synchronized (mPackages) { 3928 final PackageParser.Package p1 = mPackages.get(pkg1); 3929 final PackageParser.Package p2 = mPackages.get(pkg2); 3930 if (p1 == null || p1.mExtras == null 3931 || p2 == null || p2.mExtras == null) { 3932 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3933 } 3934 return compareSignatures(p1.mSignatures, p2.mSignatures); 3935 } 3936 } 3937 3938 @Override 3939 public int checkUidSignatures(int uid1, int uid2) { 3940 // Map to base uids. 3941 uid1 = UserHandle.getAppId(uid1); 3942 uid2 = UserHandle.getAppId(uid2); 3943 // reader 3944 synchronized (mPackages) { 3945 Signature[] s1; 3946 Signature[] s2; 3947 Object obj = mSettings.getUserIdLPr(uid1); 3948 if (obj != null) { 3949 if (obj instanceof SharedUserSetting) { 3950 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 3951 } else if (obj instanceof PackageSetting) { 3952 s1 = ((PackageSetting)obj).signatures.mSignatures; 3953 } else { 3954 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3955 } 3956 } else { 3957 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3958 } 3959 obj = mSettings.getUserIdLPr(uid2); 3960 if (obj != null) { 3961 if (obj instanceof SharedUserSetting) { 3962 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 3963 } else if (obj instanceof PackageSetting) { 3964 s2 = ((PackageSetting)obj).signatures.mSignatures; 3965 } else { 3966 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3967 } 3968 } else { 3969 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3970 } 3971 return compareSignatures(s1, s2); 3972 } 3973 } 3974 3975 private void killUid(int appId, int userId, String reason) { 3976 final long identity = Binder.clearCallingIdentity(); 3977 try { 3978 IActivityManager am = ActivityManagerNative.getDefault(); 3979 if (am != null) { 3980 try { 3981 am.killUid(appId, userId, reason); 3982 } catch (RemoteException e) { 3983 /* ignore - same process */ 3984 } 3985 } 3986 } finally { 3987 Binder.restoreCallingIdentity(identity); 3988 } 3989 } 3990 3991 /** 3992 * Compares two sets of signatures. Returns: 3993 * <br /> 3994 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 3995 * <br /> 3996 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 3997 * <br /> 3998 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 3999 * <br /> 4000 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4001 * <br /> 4002 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4003 */ 4004 static int compareSignatures(Signature[] s1, Signature[] s2) { 4005 if (s1 == null) { 4006 return s2 == null 4007 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4008 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4009 } 4010 4011 if (s2 == null) { 4012 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4013 } 4014 4015 if (s1.length != s2.length) { 4016 return PackageManager.SIGNATURE_NO_MATCH; 4017 } 4018 4019 // Since both signature sets are of size 1, we can compare without HashSets. 4020 if (s1.length == 1) { 4021 return s1[0].equals(s2[0]) ? 4022 PackageManager.SIGNATURE_MATCH : 4023 PackageManager.SIGNATURE_NO_MATCH; 4024 } 4025 4026 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4027 for (Signature sig : s1) { 4028 set1.add(sig); 4029 } 4030 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4031 for (Signature sig : s2) { 4032 set2.add(sig); 4033 } 4034 // Make sure s2 contains all signatures in s1. 4035 if (set1.equals(set2)) { 4036 return PackageManager.SIGNATURE_MATCH; 4037 } 4038 return PackageManager.SIGNATURE_NO_MATCH; 4039 } 4040 4041 /** 4042 * If the database version for this type of package (internal storage or 4043 * external storage) is less than the version where package signatures 4044 * were updated, return true. 4045 */ 4046 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4047 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4048 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4049 } 4050 4051 /** 4052 * Used for backward compatibility to make sure any packages with 4053 * certificate chains get upgraded to the new style. {@code existingSigs} 4054 * will be in the old format (since they were stored on disk from before the 4055 * system upgrade) and {@code scannedSigs} will be in the newer format. 4056 */ 4057 private int compareSignaturesCompat(PackageSignatures existingSigs, 4058 PackageParser.Package scannedPkg) { 4059 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4060 return PackageManager.SIGNATURE_NO_MATCH; 4061 } 4062 4063 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4064 for (Signature sig : existingSigs.mSignatures) { 4065 existingSet.add(sig); 4066 } 4067 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4068 for (Signature sig : scannedPkg.mSignatures) { 4069 try { 4070 Signature[] chainSignatures = sig.getChainSignatures(); 4071 for (Signature chainSig : chainSignatures) { 4072 scannedCompatSet.add(chainSig); 4073 } 4074 } catch (CertificateEncodingException e) { 4075 scannedCompatSet.add(sig); 4076 } 4077 } 4078 /* 4079 * Make sure the expanded scanned set contains all signatures in the 4080 * existing one. 4081 */ 4082 if (scannedCompatSet.equals(existingSet)) { 4083 // Migrate the old signatures to the new scheme. 4084 existingSigs.assignSignatures(scannedPkg.mSignatures); 4085 // The new KeySets will be re-added later in the scanning process. 4086 synchronized (mPackages) { 4087 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4088 } 4089 return PackageManager.SIGNATURE_MATCH; 4090 } 4091 return PackageManager.SIGNATURE_NO_MATCH; 4092 } 4093 4094 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4095 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4096 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4097 } 4098 4099 private int compareSignaturesRecover(PackageSignatures existingSigs, 4100 PackageParser.Package scannedPkg) { 4101 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4102 return PackageManager.SIGNATURE_NO_MATCH; 4103 } 4104 4105 String msg = null; 4106 try { 4107 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4108 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4109 + scannedPkg.packageName); 4110 return PackageManager.SIGNATURE_MATCH; 4111 } 4112 } catch (CertificateException e) { 4113 msg = e.getMessage(); 4114 } 4115 4116 logCriticalInfo(Log.INFO, 4117 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4118 return PackageManager.SIGNATURE_NO_MATCH; 4119 } 4120 4121 @Override 4122 public String[] getPackagesForUid(int uid) { 4123 uid = UserHandle.getAppId(uid); 4124 // reader 4125 synchronized (mPackages) { 4126 Object obj = mSettings.getUserIdLPr(uid); 4127 if (obj instanceof SharedUserSetting) { 4128 final SharedUserSetting sus = (SharedUserSetting) obj; 4129 final int N = sus.packages.size(); 4130 final String[] res = new String[N]; 4131 final Iterator<PackageSetting> it = sus.packages.iterator(); 4132 int i = 0; 4133 while (it.hasNext()) { 4134 res[i++] = it.next().name; 4135 } 4136 return res; 4137 } else if (obj instanceof PackageSetting) { 4138 final PackageSetting ps = (PackageSetting) obj; 4139 return new String[] { ps.name }; 4140 } 4141 } 4142 return null; 4143 } 4144 4145 @Override 4146 public String getNameForUid(int uid) { 4147 // reader 4148 synchronized (mPackages) { 4149 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4150 if (obj instanceof SharedUserSetting) { 4151 final SharedUserSetting sus = (SharedUserSetting) obj; 4152 return sus.name + ":" + sus.userId; 4153 } else if (obj instanceof PackageSetting) { 4154 final PackageSetting ps = (PackageSetting) obj; 4155 return ps.name; 4156 } 4157 } 4158 return null; 4159 } 4160 4161 @Override 4162 public int getUidForSharedUser(String sharedUserName) { 4163 if(sharedUserName == null) { 4164 return -1; 4165 } 4166 // reader 4167 synchronized (mPackages) { 4168 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4169 if (suid == null) { 4170 return -1; 4171 } 4172 return suid.userId; 4173 } 4174 } 4175 4176 @Override 4177 public int getFlagsForUid(int uid) { 4178 synchronized (mPackages) { 4179 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4180 if (obj instanceof SharedUserSetting) { 4181 final SharedUserSetting sus = (SharedUserSetting) obj; 4182 return sus.pkgFlags; 4183 } else if (obj instanceof PackageSetting) { 4184 final PackageSetting ps = (PackageSetting) obj; 4185 return ps.pkgFlags; 4186 } 4187 } 4188 return 0; 4189 } 4190 4191 @Override 4192 public int getPrivateFlagsForUid(int uid) { 4193 synchronized (mPackages) { 4194 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4195 if (obj instanceof SharedUserSetting) { 4196 final SharedUserSetting sus = (SharedUserSetting) obj; 4197 return sus.pkgPrivateFlags; 4198 } else if (obj instanceof PackageSetting) { 4199 final PackageSetting ps = (PackageSetting) obj; 4200 return ps.pkgPrivateFlags; 4201 } 4202 } 4203 return 0; 4204 } 4205 4206 @Override 4207 public boolean isUidPrivileged(int uid) { 4208 uid = UserHandle.getAppId(uid); 4209 // reader 4210 synchronized (mPackages) { 4211 Object obj = mSettings.getUserIdLPr(uid); 4212 if (obj instanceof SharedUserSetting) { 4213 final SharedUserSetting sus = (SharedUserSetting) obj; 4214 final Iterator<PackageSetting> it = sus.packages.iterator(); 4215 while (it.hasNext()) { 4216 if (it.next().isPrivileged()) { 4217 return true; 4218 } 4219 } 4220 } else if (obj instanceof PackageSetting) { 4221 final PackageSetting ps = (PackageSetting) obj; 4222 return ps.isPrivileged(); 4223 } 4224 } 4225 return false; 4226 } 4227 4228 @Override 4229 public String[] getAppOpPermissionPackages(String permissionName) { 4230 synchronized (mPackages) { 4231 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4232 if (pkgs == null) { 4233 return null; 4234 } 4235 return pkgs.toArray(new String[pkgs.size()]); 4236 } 4237 } 4238 4239 @Override 4240 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4241 int flags, int userId) { 4242 if (!sUserManager.exists(userId)) return null; 4243 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 4244 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4245 return chooseBestActivity(intent, resolvedType, flags, query, userId); 4246 } 4247 4248 @Override 4249 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4250 IntentFilter filter, int match, ComponentName activity) { 4251 final int userId = UserHandle.getCallingUserId(); 4252 if (DEBUG_PREFERRED) { 4253 Log.v(TAG, "setLastChosenActivity intent=" + intent 4254 + " resolvedType=" + resolvedType 4255 + " flags=" + flags 4256 + " filter=" + filter 4257 + " match=" + match 4258 + " activity=" + activity); 4259 filter.dump(new PrintStreamPrinter(System.out), " "); 4260 } 4261 intent.setComponent(null); 4262 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4263 // Find any earlier preferred or last chosen entries and nuke them 4264 findPreferredActivity(intent, resolvedType, 4265 flags, query, 0, false, true, false, userId); 4266 // Add the new activity as the last chosen for this filter 4267 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4268 "Setting last chosen"); 4269 } 4270 4271 @Override 4272 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4273 final int userId = UserHandle.getCallingUserId(); 4274 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4275 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4276 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4277 false, false, false, userId); 4278 } 4279 4280 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4281 int flags, List<ResolveInfo> query, int userId) { 4282 if (query != null) { 4283 final int N = query.size(); 4284 if (N == 1) { 4285 return query.get(0); 4286 } else if (N > 1) { 4287 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4288 // If there is more than one activity with the same priority, 4289 // then let the user decide between them. 4290 ResolveInfo r0 = query.get(0); 4291 ResolveInfo r1 = query.get(1); 4292 if (DEBUG_INTENT_MATCHING || debug) { 4293 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4294 + r1.activityInfo.name + "=" + r1.priority); 4295 } 4296 // If the first activity has a higher priority, or a different 4297 // default, then it is always desireable to pick it. 4298 if (r0.priority != r1.priority 4299 || r0.preferredOrder != r1.preferredOrder 4300 || r0.isDefault != r1.isDefault) { 4301 return query.get(0); 4302 } 4303 // If we have saved a preference for a preferred activity for 4304 // this Intent, use that. 4305 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4306 flags, query, r0.priority, true, false, debug, userId); 4307 if (ri != null) { 4308 return ri; 4309 } 4310 ri = new ResolveInfo(mResolveInfo); 4311 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4312 ri.activityInfo.applicationInfo = new ApplicationInfo( 4313 ri.activityInfo.applicationInfo); 4314 if (userId != 0) { 4315 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4316 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4317 } 4318 // Make sure that the resolver is displayable in car mode 4319 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4320 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4321 return ri; 4322 } 4323 } 4324 return null; 4325 } 4326 4327 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4328 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4329 final int N = query.size(); 4330 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4331 .get(userId); 4332 // Get the list of persistent preferred activities that handle the intent 4333 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4334 List<PersistentPreferredActivity> pprefs = ppir != null 4335 ? ppir.queryIntent(intent, resolvedType, 4336 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4337 : null; 4338 if (pprefs != null && pprefs.size() > 0) { 4339 final int M = pprefs.size(); 4340 for (int i=0; i<M; i++) { 4341 final PersistentPreferredActivity ppa = pprefs.get(i); 4342 if (DEBUG_PREFERRED || debug) { 4343 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4344 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4345 + "\n component=" + ppa.mComponent); 4346 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4347 } 4348 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4349 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 4350 if (DEBUG_PREFERRED || debug) { 4351 Slog.v(TAG, "Found persistent preferred activity:"); 4352 if (ai != null) { 4353 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4354 } else { 4355 Slog.v(TAG, " null"); 4356 } 4357 } 4358 if (ai == null) { 4359 // This previously registered persistent preferred activity 4360 // component is no longer known. Ignore it and do NOT remove it. 4361 continue; 4362 } 4363 for (int j=0; j<N; j++) { 4364 final ResolveInfo ri = query.get(j); 4365 if (!ri.activityInfo.applicationInfo.packageName 4366 .equals(ai.applicationInfo.packageName)) { 4367 continue; 4368 } 4369 if (!ri.activityInfo.name.equals(ai.name)) { 4370 continue; 4371 } 4372 // Found a persistent preference that can handle the intent. 4373 if (DEBUG_PREFERRED || debug) { 4374 Slog.v(TAG, "Returning persistent preferred activity: " + 4375 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4376 } 4377 return ri; 4378 } 4379 } 4380 } 4381 return null; 4382 } 4383 4384 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4385 List<ResolveInfo> query, int priority, boolean always, 4386 boolean removeMatches, boolean debug, int userId) { 4387 if (!sUserManager.exists(userId)) return null; 4388 // writer 4389 synchronized (mPackages) { 4390 if (intent.getSelector() != null) { 4391 intent = intent.getSelector(); 4392 } 4393 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4394 4395 // Try to find a matching persistent preferred activity. 4396 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4397 debug, userId); 4398 4399 // If a persistent preferred activity matched, use it. 4400 if (pri != null) { 4401 return pri; 4402 } 4403 4404 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4405 // Get the list of preferred activities that handle the intent 4406 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4407 List<PreferredActivity> prefs = pir != null 4408 ? pir.queryIntent(intent, resolvedType, 4409 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4410 : null; 4411 if (prefs != null && prefs.size() > 0) { 4412 boolean changed = false; 4413 try { 4414 // First figure out how good the original match set is. 4415 // We will only allow preferred activities that came 4416 // from the same match quality. 4417 int match = 0; 4418 4419 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4420 4421 final int N = query.size(); 4422 for (int j=0; j<N; j++) { 4423 final ResolveInfo ri = query.get(j); 4424 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4425 + ": 0x" + Integer.toHexString(match)); 4426 if (ri.match > match) { 4427 match = ri.match; 4428 } 4429 } 4430 4431 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4432 + Integer.toHexString(match)); 4433 4434 match &= IntentFilter.MATCH_CATEGORY_MASK; 4435 final int M = prefs.size(); 4436 for (int i=0; i<M; i++) { 4437 final PreferredActivity pa = prefs.get(i); 4438 if (DEBUG_PREFERRED || debug) { 4439 Slog.v(TAG, "Checking PreferredActivity ds=" 4440 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4441 + "\n component=" + pa.mPref.mComponent); 4442 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4443 } 4444 if (pa.mPref.mMatch != match) { 4445 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4446 + Integer.toHexString(pa.mPref.mMatch)); 4447 continue; 4448 } 4449 // If it's not an "always" type preferred activity and that's what we're 4450 // looking for, skip it. 4451 if (always && !pa.mPref.mAlways) { 4452 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4453 continue; 4454 } 4455 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4456 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 4457 if (DEBUG_PREFERRED || debug) { 4458 Slog.v(TAG, "Found preferred activity:"); 4459 if (ai != null) { 4460 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4461 } else { 4462 Slog.v(TAG, " null"); 4463 } 4464 } 4465 if (ai == null) { 4466 // This previously registered preferred activity 4467 // component is no longer known. Most likely an update 4468 // to the app was installed and in the new version this 4469 // component no longer exists. Clean it up by removing 4470 // it from the preferred activities list, and skip it. 4471 Slog.w(TAG, "Removing dangling preferred activity: " 4472 + pa.mPref.mComponent); 4473 pir.removeFilter(pa); 4474 changed = true; 4475 continue; 4476 } 4477 for (int j=0; j<N; j++) { 4478 final ResolveInfo ri = query.get(j); 4479 if (!ri.activityInfo.applicationInfo.packageName 4480 .equals(ai.applicationInfo.packageName)) { 4481 continue; 4482 } 4483 if (!ri.activityInfo.name.equals(ai.name)) { 4484 continue; 4485 } 4486 4487 if (removeMatches) { 4488 pir.removeFilter(pa); 4489 changed = true; 4490 if (DEBUG_PREFERRED) { 4491 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4492 } 4493 break; 4494 } 4495 4496 // Okay we found a previously set preferred or last chosen app. 4497 // If the result set is different from when this 4498 // was created, we need to clear it and re-ask the 4499 // user their preference, if we're looking for an "always" type entry. 4500 if (always && !pa.mPref.sameSet(query)) { 4501 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4502 + intent + " type " + resolvedType); 4503 if (DEBUG_PREFERRED) { 4504 Slog.v(TAG, "Removing preferred activity since set changed " 4505 + pa.mPref.mComponent); 4506 } 4507 pir.removeFilter(pa); 4508 // Re-add the filter as a "last chosen" entry (!always) 4509 PreferredActivity lastChosen = new PreferredActivity( 4510 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4511 pir.addFilter(lastChosen); 4512 changed = true; 4513 return null; 4514 } 4515 4516 // Yay! Either the set matched or we're looking for the last chosen 4517 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4518 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4519 return ri; 4520 } 4521 } 4522 } finally { 4523 if (changed) { 4524 if (DEBUG_PREFERRED) { 4525 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 4526 } 4527 scheduleWritePackageRestrictionsLocked(userId); 4528 } 4529 } 4530 } 4531 } 4532 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 4533 return null; 4534 } 4535 4536 /* 4537 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 4538 */ 4539 @Override 4540 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 4541 int targetUserId) { 4542 mContext.enforceCallingOrSelfPermission( 4543 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 4544 List<CrossProfileIntentFilter> matches = 4545 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 4546 if (matches != null) { 4547 int size = matches.size(); 4548 for (int i = 0; i < size; i++) { 4549 if (matches.get(i).getTargetUserId() == targetUserId) return true; 4550 } 4551 } 4552 if (hasWebURI(intent)) { 4553 // cross-profile app linking works only towards the parent. 4554 final UserInfo parent = getProfileParent(sourceUserId); 4555 synchronized(mPackages) { 4556 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 4557 intent, resolvedType, 0, sourceUserId, parent.id); 4558 return xpDomainInfo != null; 4559 } 4560 } 4561 return false; 4562 } 4563 4564 private UserInfo getProfileParent(int userId) { 4565 final long identity = Binder.clearCallingIdentity(); 4566 try { 4567 return sUserManager.getProfileParent(userId); 4568 } finally { 4569 Binder.restoreCallingIdentity(identity); 4570 } 4571 } 4572 4573 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 4574 String resolvedType, int userId) { 4575 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 4576 if (resolver != null) { 4577 return resolver.queryIntent(intent, resolvedType, false, userId); 4578 } 4579 return null; 4580 } 4581 4582 @Override 4583 public List<ResolveInfo> queryIntentActivities(Intent intent, 4584 String resolvedType, int flags, int userId) { 4585 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4586 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 4587 ComponentName comp = intent.getComponent(); 4588 if (comp == null) { 4589 if (intent.getSelector() != null) { 4590 intent = intent.getSelector(); 4591 comp = intent.getComponent(); 4592 } 4593 } 4594 4595 if (comp != null) { 4596 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4597 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 4598 if (ai != null) { 4599 final ResolveInfo ri = new ResolveInfo(); 4600 ri.activityInfo = ai; 4601 list.add(ri); 4602 } 4603 return list; 4604 } 4605 4606 // reader 4607 synchronized (mPackages) { 4608 final String pkgName = intent.getPackage(); 4609 if (pkgName == null) { 4610 List<CrossProfileIntentFilter> matchingFilters = 4611 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 4612 // Check for results that need to skip the current profile. 4613 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 4614 resolvedType, flags, userId); 4615 if (xpResolveInfo != null) { 4616 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 4617 result.add(xpResolveInfo); 4618 return filterIfNotSystemUser(result, userId); 4619 } 4620 4621 // Check for results in the current profile. 4622 List<ResolveInfo> result = mActivities.queryIntent( 4623 intent, resolvedType, flags, userId); 4624 4625 // Check for cross profile results. 4626 xpResolveInfo = queryCrossProfileIntents( 4627 matchingFilters, intent, resolvedType, flags, userId); 4628 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 4629 result.add(xpResolveInfo); 4630 Collections.sort(result, mResolvePrioritySorter); 4631 } 4632 result = filterIfNotSystemUser(result, userId); 4633 if (hasWebURI(intent)) { 4634 CrossProfileDomainInfo xpDomainInfo = null; 4635 final UserInfo parent = getProfileParent(userId); 4636 if (parent != null) { 4637 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 4638 flags, userId, parent.id); 4639 } 4640 if (xpDomainInfo != null) { 4641 if (xpResolveInfo != null) { 4642 // If we didn't remove it, the cross-profile ResolveInfo would be twice 4643 // in the result. 4644 result.remove(xpResolveInfo); 4645 } 4646 if (result.size() == 0) { 4647 result.add(xpDomainInfo.resolveInfo); 4648 return result; 4649 } 4650 } else if (result.size() <= 1) { 4651 return result; 4652 } 4653 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 4654 xpDomainInfo, userId); 4655 Collections.sort(result, mResolvePrioritySorter); 4656 } 4657 return result; 4658 } 4659 final PackageParser.Package pkg = mPackages.get(pkgName); 4660 if (pkg != null) { 4661 return filterIfNotSystemUser( 4662 mActivities.queryIntentForPackage( 4663 intent, resolvedType, flags, pkg.activities, userId), 4664 userId); 4665 } 4666 return new ArrayList<ResolveInfo>(); 4667 } 4668 } 4669 4670 private static class CrossProfileDomainInfo { 4671 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 4672 ResolveInfo resolveInfo; 4673 /* Best domain verification status of the activities found in the other profile */ 4674 int bestDomainVerificationStatus; 4675 } 4676 4677 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 4678 String resolvedType, int flags, int sourceUserId, int parentUserId) { 4679 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 4680 sourceUserId)) { 4681 return null; 4682 } 4683 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4684 resolvedType, flags, parentUserId); 4685 4686 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 4687 return null; 4688 } 4689 CrossProfileDomainInfo result = null; 4690 int size = resultTargetUser.size(); 4691 for (int i = 0; i < size; i++) { 4692 ResolveInfo riTargetUser = resultTargetUser.get(i); 4693 // Intent filter verification is only for filters that specify a host. So don't return 4694 // those that handle all web uris. 4695 if (riTargetUser.handleAllWebDataURI) { 4696 continue; 4697 } 4698 String packageName = riTargetUser.activityInfo.packageName; 4699 PackageSetting ps = mSettings.mPackages.get(packageName); 4700 if (ps == null) { 4701 continue; 4702 } 4703 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 4704 int status = (int)(verificationState >> 32); 4705 if (result == null) { 4706 result = new CrossProfileDomainInfo(); 4707 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 4708 sourceUserId, parentUserId); 4709 result.bestDomainVerificationStatus = status; 4710 } else { 4711 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 4712 result.bestDomainVerificationStatus); 4713 } 4714 } 4715 // Don't consider matches with status NEVER across profiles. 4716 if (result != null && result.bestDomainVerificationStatus 4717 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4718 return null; 4719 } 4720 return result; 4721 } 4722 4723 /** 4724 * Verification statuses are ordered from the worse to the best, except for 4725 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 4726 */ 4727 private int bestDomainVerificationStatus(int status1, int status2) { 4728 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4729 return status2; 4730 } 4731 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4732 return status1; 4733 } 4734 return (int) MathUtils.max(status1, status2); 4735 } 4736 4737 private boolean isUserEnabled(int userId) { 4738 long callingId = Binder.clearCallingIdentity(); 4739 try { 4740 UserInfo userInfo = sUserManager.getUserInfo(userId); 4741 return userInfo != null && userInfo.isEnabled(); 4742 } finally { 4743 Binder.restoreCallingIdentity(callingId); 4744 } 4745 } 4746 4747 /** 4748 * Filter out activities with systemUserOnly flag set, when current user is not System. 4749 * 4750 * @return filtered list 4751 */ 4752 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 4753 if (userId == UserHandle.USER_SYSTEM) { 4754 return resolveInfos; 4755 } 4756 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 4757 ResolveInfo info = resolveInfos.get(i); 4758 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 4759 resolveInfos.remove(i); 4760 } 4761 } 4762 return resolveInfos; 4763 } 4764 4765 private static boolean hasWebURI(Intent intent) { 4766 if (intent.getData() == null) { 4767 return false; 4768 } 4769 final String scheme = intent.getScheme(); 4770 if (TextUtils.isEmpty(scheme)) { 4771 return false; 4772 } 4773 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 4774 } 4775 4776 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 4777 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 4778 int userId) { 4779 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 4780 4781 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 4782 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 4783 candidates.size()); 4784 } 4785 4786 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 4787 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 4788 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 4789 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 4790 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 4791 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 4792 4793 synchronized (mPackages) { 4794 final int count = candidates.size(); 4795 // First, try to use linked apps. Partition the candidates into four lists: 4796 // one for the final results, one for the "do not use ever", one for "undefined status" 4797 // and finally one for "browser app type". 4798 for (int n=0; n<count; n++) { 4799 ResolveInfo info = candidates.get(n); 4800 String packageName = info.activityInfo.packageName; 4801 PackageSetting ps = mSettings.mPackages.get(packageName); 4802 if (ps != null) { 4803 // Add to the special match all list (Browser use case) 4804 if (info.handleAllWebDataURI) { 4805 matchAllList.add(info); 4806 continue; 4807 } 4808 // Try to get the status from User settings first 4809 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4810 int status = (int)(packedStatus >> 32); 4811 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 4812 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 4813 if (DEBUG_DOMAIN_VERIFICATION) { 4814 Slog.i(TAG, " + always: " + info.activityInfo.packageName 4815 + " : linkgen=" + linkGeneration); 4816 } 4817 // Use link-enabled generation as preferredOrder, i.e. 4818 // prefer newly-enabled over earlier-enabled. 4819 info.preferredOrder = linkGeneration; 4820 alwaysList.add(info); 4821 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4822 if (DEBUG_DOMAIN_VERIFICATION) { 4823 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 4824 } 4825 neverList.add(info); 4826 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4827 if (DEBUG_DOMAIN_VERIFICATION) { 4828 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 4829 } 4830 alwaysAskList.add(info); 4831 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 4832 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 4833 if (DEBUG_DOMAIN_VERIFICATION) { 4834 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 4835 } 4836 undefinedList.add(info); 4837 } 4838 } 4839 } 4840 4841 // We'll want to include browser possibilities in a few cases 4842 boolean includeBrowser = false; 4843 4844 // First try to add the "always" resolution(s) for the current user, if any 4845 if (alwaysList.size() > 0) { 4846 result.addAll(alwaysList); 4847 } else { 4848 // Add all undefined apps as we want them to appear in the disambiguation dialog. 4849 result.addAll(undefinedList); 4850 // Maybe add one for the other profile. 4851 if (xpDomainInfo != null && ( 4852 xpDomainInfo.bestDomainVerificationStatus 4853 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 4854 result.add(xpDomainInfo.resolveInfo); 4855 } 4856 includeBrowser = true; 4857 } 4858 4859 // The presence of any 'always ask' alternatives means we'll also offer browsers. 4860 // If there were 'always' entries their preferred order has been set, so we also 4861 // back that off to make the alternatives equivalent 4862 if (alwaysAskList.size() > 0) { 4863 for (ResolveInfo i : result) { 4864 i.preferredOrder = 0; 4865 } 4866 result.addAll(alwaysAskList); 4867 includeBrowser = true; 4868 } 4869 4870 if (includeBrowser) { 4871 // Also add browsers (all of them or only the default one) 4872 if (DEBUG_DOMAIN_VERIFICATION) { 4873 Slog.v(TAG, " ...including browsers in candidate set"); 4874 } 4875 if ((matchFlags & MATCH_ALL) != 0) { 4876 result.addAll(matchAllList); 4877 } else { 4878 // Browser/generic handling case. If there's a default browser, go straight 4879 // to that (but only if there is no other higher-priority match). 4880 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 4881 int maxMatchPrio = 0; 4882 ResolveInfo defaultBrowserMatch = null; 4883 final int numCandidates = matchAllList.size(); 4884 for (int n = 0; n < numCandidates; n++) { 4885 ResolveInfo info = matchAllList.get(n); 4886 // track the highest overall match priority... 4887 if (info.priority > maxMatchPrio) { 4888 maxMatchPrio = info.priority; 4889 } 4890 // ...and the highest-priority default browser match 4891 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 4892 if (defaultBrowserMatch == null 4893 || (defaultBrowserMatch.priority < info.priority)) { 4894 if (debug) { 4895 Slog.v(TAG, "Considering default browser match " + info); 4896 } 4897 defaultBrowserMatch = info; 4898 } 4899 } 4900 } 4901 if (defaultBrowserMatch != null 4902 && defaultBrowserMatch.priority >= maxMatchPrio 4903 && !TextUtils.isEmpty(defaultBrowserPackageName)) 4904 { 4905 if (debug) { 4906 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 4907 } 4908 result.add(defaultBrowserMatch); 4909 } else { 4910 result.addAll(matchAllList); 4911 } 4912 } 4913 4914 // If there is nothing selected, add all candidates and remove the ones that the user 4915 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 4916 if (result.size() == 0) { 4917 result.addAll(candidates); 4918 result.removeAll(neverList); 4919 } 4920 } 4921 } 4922 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 4923 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 4924 result.size()); 4925 for (ResolveInfo info : result) { 4926 Slog.v(TAG, " + " + info.activityInfo); 4927 } 4928 } 4929 return result; 4930 } 4931 4932 // Returns a packed value as a long: 4933 // 4934 // high 'int'-sized word: link status: undefined/ask/never/always. 4935 // low 'int'-sized word: relative priority among 'always' results. 4936 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 4937 long result = ps.getDomainVerificationStatusForUser(userId); 4938 // if none available, get the master status 4939 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4940 if (ps.getIntentFilterVerificationInfo() != null) { 4941 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 4942 } 4943 } 4944 return result; 4945 } 4946 4947 private ResolveInfo querySkipCurrentProfileIntents( 4948 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4949 int flags, int sourceUserId) { 4950 if (matchingFilters != null) { 4951 int size = matchingFilters.size(); 4952 for (int i = 0; i < size; i ++) { 4953 CrossProfileIntentFilter filter = matchingFilters.get(i); 4954 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 4955 // Checking if there are activities in the target user that can handle the 4956 // intent. 4957 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 4958 resolvedType, flags, sourceUserId); 4959 if (resolveInfo != null) { 4960 return resolveInfo; 4961 } 4962 } 4963 } 4964 } 4965 return null; 4966 } 4967 4968 // Return matching ResolveInfo if any for skip current profile intent filters. 4969 private ResolveInfo queryCrossProfileIntents( 4970 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4971 int flags, int sourceUserId) { 4972 if (matchingFilters != null) { 4973 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 4974 // match the same intent. For performance reasons, it is better not to 4975 // run queryIntent twice for the same userId 4976 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 4977 int size = matchingFilters.size(); 4978 for (int i = 0; i < size; i++) { 4979 CrossProfileIntentFilter filter = matchingFilters.get(i); 4980 int targetUserId = filter.getTargetUserId(); 4981 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 4982 && !alreadyTriedUserIds.get(targetUserId)) { 4983 // Checking if there are activities in the target user that can handle the 4984 // intent. 4985 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 4986 resolvedType, flags, sourceUserId); 4987 if (resolveInfo != null) return resolveInfo; 4988 alreadyTriedUserIds.put(targetUserId, true); 4989 } 4990 } 4991 } 4992 return null; 4993 } 4994 4995 /** 4996 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 4997 * will forward the intent to the filter's target user. 4998 * Otherwise, returns null. 4999 */ 5000 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5001 String resolvedType, int flags, int sourceUserId) { 5002 int targetUserId = filter.getTargetUserId(); 5003 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5004 resolvedType, flags, targetUserId); 5005 if (resultTargetUser != null && !resultTargetUser.isEmpty() 5006 && isUserEnabled(targetUserId)) { 5007 return createForwardingResolveInfoUnchecked(filter, sourceUserId, targetUserId); 5008 } 5009 return null; 5010 } 5011 5012 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5013 int sourceUserId, int targetUserId) { 5014 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5015 long ident = Binder.clearCallingIdentity(); 5016 boolean targetIsProfile; 5017 try { 5018 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5019 } finally { 5020 Binder.restoreCallingIdentity(ident); 5021 } 5022 String className; 5023 if (targetIsProfile) { 5024 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5025 } else { 5026 className = FORWARD_INTENT_TO_PARENT; 5027 } 5028 ComponentName forwardingActivityComponentName = new ComponentName( 5029 mAndroidApplication.packageName, className); 5030 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5031 sourceUserId); 5032 if (!targetIsProfile) { 5033 forwardingActivityInfo.showUserIcon = targetUserId; 5034 forwardingResolveInfo.noResourceId = true; 5035 } 5036 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5037 forwardingResolveInfo.priority = 0; 5038 forwardingResolveInfo.preferredOrder = 0; 5039 forwardingResolveInfo.match = 0; 5040 forwardingResolveInfo.isDefault = true; 5041 forwardingResolveInfo.filter = filter; 5042 forwardingResolveInfo.targetUserId = targetUserId; 5043 return forwardingResolveInfo; 5044 } 5045 5046 @Override 5047 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5048 Intent[] specifics, String[] specificTypes, Intent intent, 5049 String resolvedType, int flags, int userId) { 5050 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5051 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 5052 false, "query intent activity options"); 5053 final String resultsAction = intent.getAction(); 5054 5055 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 5056 | PackageManager.GET_RESOLVED_FILTER, userId); 5057 5058 if (DEBUG_INTENT_MATCHING) { 5059 Log.v(TAG, "Query " + intent + ": " + results); 5060 } 5061 5062 int specificsPos = 0; 5063 int N; 5064 5065 // todo: note that the algorithm used here is O(N^2). This 5066 // isn't a problem in our current environment, but if we start running 5067 // into situations where we have more than 5 or 10 matches then this 5068 // should probably be changed to something smarter... 5069 5070 // First we go through and resolve each of the specific items 5071 // that were supplied, taking care of removing any corresponding 5072 // duplicate items in the generic resolve list. 5073 if (specifics != null) { 5074 for (int i=0; i<specifics.length; i++) { 5075 final Intent sintent = specifics[i]; 5076 if (sintent == null) { 5077 continue; 5078 } 5079 5080 if (DEBUG_INTENT_MATCHING) { 5081 Log.v(TAG, "Specific #" + i + ": " + sintent); 5082 } 5083 5084 String action = sintent.getAction(); 5085 if (resultsAction != null && resultsAction.equals(action)) { 5086 // If this action was explicitly requested, then don't 5087 // remove things that have it. 5088 action = null; 5089 } 5090 5091 ResolveInfo ri = null; 5092 ActivityInfo ai = null; 5093 5094 ComponentName comp = sintent.getComponent(); 5095 if (comp == null) { 5096 ri = resolveIntent( 5097 sintent, 5098 specificTypes != null ? specificTypes[i] : null, 5099 flags, userId); 5100 if (ri == null) { 5101 continue; 5102 } 5103 if (ri == mResolveInfo) { 5104 // ACK! Must do something better with this. 5105 } 5106 ai = ri.activityInfo; 5107 comp = new ComponentName(ai.applicationInfo.packageName, 5108 ai.name); 5109 } else { 5110 ai = getActivityInfo(comp, flags, userId); 5111 if (ai == null) { 5112 continue; 5113 } 5114 } 5115 5116 // Look for any generic query activities that are duplicates 5117 // of this specific one, and remove them from the results. 5118 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5119 N = results.size(); 5120 int j; 5121 for (j=specificsPos; j<N; j++) { 5122 ResolveInfo sri = results.get(j); 5123 if ((sri.activityInfo.name.equals(comp.getClassName()) 5124 && sri.activityInfo.applicationInfo.packageName.equals( 5125 comp.getPackageName())) 5126 || (action != null && sri.filter.matchAction(action))) { 5127 results.remove(j); 5128 if (DEBUG_INTENT_MATCHING) Log.v( 5129 TAG, "Removing duplicate item from " + j 5130 + " due to specific " + specificsPos); 5131 if (ri == null) { 5132 ri = sri; 5133 } 5134 j--; 5135 N--; 5136 } 5137 } 5138 5139 // Add this specific item to its proper place. 5140 if (ri == null) { 5141 ri = new ResolveInfo(); 5142 ri.activityInfo = ai; 5143 } 5144 results.add(specificsPos, ri); 5145 ri.specificIndex = i; 5146 specificsPos++; 5147 } 5148 } 5149 5150 // Now we go through the remaining generic results and remove any 5151 // duplicate actions that are found here. 5152 N = results.size(); 5153 for (int i=specificsPos; i<N-1; i++) { 5154 final ResolveInfo rii = results.get(i); 5155 if (rii.filter == null) { 5156 continue; 5157 } 5158 5159 // Iterate over all of the actions of this result's intent 5160 // filter... typically this should be just one. 5161 final Iterator<String> it = rii.filter.actionsIterator(); 5162 if (it == null) { 5163 continue; 5164 } 5165 while (it.hasNext()) { 5166 final String action = it.next(); 5167 if (resultsAction != null && resultsAction.equals(action)) { 5168 // If this action was explicitly requested, then don't 5169 // remove things that have it. 5170 continue; 5171 } 5172 for (int j=i+1; j<N; j++) { 5173 final ResolveInfo rij = results.get(j); 5174 if (rij.filter != null && rij.filter.hasAction(action)) { 5175 results.remove(j); 5176 if (DEBUG_INTENT_MATCHING) Log.v( 5177 TAG, "Removing duplicate item from " + j 5178 + " due to action " + action + " at " + i); 5179 j--; 5180 N--; 5181 } 5182 } 5183 } 5184 5185 // If the caller didn't request filter information, drop it now 5186 // so we don't have to marshall/unmarshall it. 5187 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5188 rii.filter = null; 5189 } 5190 } 5191 5192 // Filter out the caller activity if so requested. 5193 if (caller != null) { 5194 N = results.size(); 5195 for (int i=0; i<N; i++) { 5196 ActivityInfo ainfo = results.get(i).activityInfo; 5197 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5198 && caller.getClassName().equals(ainfo.name)) { 5199 results.remove(i); 5200 break; 5201 } 5202 } 5203 } 5204 5205 // If the caller didn't request filter information, 5206 // drop them now so we don't have to 5207 // marshall/unmarshall it. 5208 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5209 N = results.size(); 5210 for (int i=0; i<N; i++) { 5211 results.get(i).filter = null; 5212 } 5213 } 5214 5215 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5216 return results; 5217 } 5218 5219 @Override 5220 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 5221 int userId) { 5222 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5223 ComponentName comp = intent.getComponent(); 5224 if (comp == null) { 5225 if (intent.getSelector() != null) { 5226 intent = intent.getSelector(); 5227 comp = intent.getComponent(); 5228 } 5229 } 5230 if (comp != null) { 5231 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5232 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5233 if (ai != null) { 5234 ResolveInfo ri = new ResolveInfo(); 5235 ri.activityInfo = ai; 5236 list.add(ri); 5237 } 5238 return list; 5239 } 5240 5241 // reader 5242 synchronized (mPackages) { 5243 String pkgName = intent.getPackage(); 5244 if (pkgName == null) { 5245 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5246 } 5247 final PackageParser.Package pkg = mPackages.get(pkgName); 5248 if (pkg != null) { 5249 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5250 userId); 5251 } 5252 return null; 5253 } 5254 } 5255 5256 @Override 5257 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5258 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 5259 if (!sUserManager.exists(userId)) return null; 5260 if (query != null) { 5261 if (query.size() >= 1) { 5262 // If there is more than one service with the same priority, 5263 // just arbitrarily pick the first one. 5264 return query.get(0); 5265 } 5266 } 5267 return null; 5268 } 5269 5270 @Override 5271 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 5272 int userId) { 5273 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5274 ComponentName comp = intent.getComponent(); 5275 if (comp == null) { 5276 if (intent.getSelector() != null) { 5277 intent = intent.getSelector(); 5278 comp = intent.getComponent(); 5279 } 5280 } 5281 if (comp != null) { 5282 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5283 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5284 if (si != null) { 5285 final ResolveInfo ri = new ResolveInfo(); 5286 ri.serviceInfo = si; 5287 list.add(ri); 5288 } 5289 return list; 5290 } 5291 5292 // reader 5293 synchronized (mPackages) { 5294 String pkgName = intent.getPackage(); 5295 if (pkgName == null) { 5296 return mServices.queryIntent(intent, resolvedType, flags, userId); 5297 } 5298 final PackageParser.Package pkg = mPackages.get(pkgName); 5299 if (pkg != null) { 5300 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5301 userId); 5302 } 5303 return null; 5304 } 5305 } 5306 5307 @Override 5308 public List<ResolveInfo> queryIntentContentProviders( 5309 Intent intent, String resolvedType, int flags, int userId) { 5310 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5311 ComponentName comp = intent.getComponent(); 5312 if (comp == null) { 5313 if (intent.getSelector() != null) { 5314 intent = intent.getSelector(); 5315 comp = intent.getComponent(); 5316 } 5317 } 5318 if (comp != null) { 5319 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5320 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5321 if (pi != null) { 5322 final ResolveInfo ri = new ResolveInfo(); 5323 ri.providerInfo = pi; 5324 list.add(ri); 5325 } 5326 return list; 5327 } 5328 5329 // reader 5330 synchronized (mPackages) { 5331 String pkgName = intent.getPackage(); 5332 if (pkgName == null) { 5333 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5334 } 5335 final PackageParser.Package pkg = mPackages.get(pkgName); 5336 if (pkg != null) { 5337 return mProviders.queryIntentForPackage( 5338 intent, resolvedType, flags, pkg.providers, userId); 5339 } 5340 return null; 5341 } 5342 } 5343 5344 @Override 5345 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5346 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5347 5348 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 5349 5350 // writer 5351 synchronized (mPackages) { 5352 ArrayList<PackageInfo> list; 5353 if (listUninstalled) { 5354 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5355 for (PackageSetting ps : mSettings.mPackages.values()) { 5356 PackageInfo pi; 5357 if (ps.pkg != null) { 5358 pi = generatePackageInfo(ps.pkg, flags, userId); 5359 } else { 5360 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5361 } 5362 if (pi != null) { 5363 list.add(pi); 5364 } 5365 } 5366 } else { 5367 list = new ArrayList<PackageInfo>(mPackages.size()); 5368 for (PackageParser.Package p : mPackages.values()) { 5369 PackageInfo pi = generatePackageInfo(p, flags, userId); 5370 if (pi != null) { 5371 list.add(pi); 5372 } 5373 } 5374 } 5375 5376 return new ParceledListSlice<PackageInfo>(list); 5377 } 5378 } 5379 5380 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5381 String[] permissions, boolean[] tmp, int flags, int userId) { 5382 int numMatch = 0; 5383 final PermissionsState permissionsState = ps.getPermissionsState(); 5384 for (int i=0; i<permissions.length; i++) { 5385 final String permission = permissions[i]; 5386 if (permissionsState.hasPermission(permission, userId)) { 5387 tmp[i] = true; 5388 numMatch++; 5389 } else { 5390 tmp[i] = false; 5391 } 5392 } 5393 if (numMatch == 0) { 5394 return; 5395 } 5396 PackageInfo pi; 5397 if (ps.pkg != null) { 5398 pi = generatePackageInfo(ps.pkg, flags, userId); 5399 } else { 5400 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5401 } 5402 // The above might return null in cases of uninstalled apps or install-state 5403 // skew across users/profiles. 5404 if (pi != null) { 5405 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5406 if (numMatch == permissions.length) { 5407 pi.requestedPermissions = permissions; 5408 } else { 5409 pi.requestedPermissions = new String[numMatch]; 5410 numMatch = 0; 5411 for (int i=0; i<permissions.length; i++) { 5412 if (tmp[i]) { 5413 pi.requestedPermissions[numMatch] = permissions[i]; 5414 numMatch++; 5415 } 5416 } 5417 } 5418 } 5419 list.add(pi); 5420 } 5421 } 5422 5423 @Override 5424 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5425 String[] permissions, int flags, int userId) { 5426 if (!sUserManager.exists(userId)) return null; 5427 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5428 5429 // writer 5430 synchronized (mPackages) { 5431 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5432 boolean[] tmpBools = new boolean[permissions.length]; 5433 if (listUninstalled) { 5434 for (PackageSetting ps : mSettings.mPackages.values()) { 5435 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5436 } 5437 } else { 5438 for (PackageParser.Package pkg : mPackages.values()) { 5439 PackageSetting ps = (PackageSetting)pkg.mExtras; 5440 if (ps != null) { 5441 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5442 userId); 5443 } 5444 } 5445 } 5446 5447 return new ParceledListSlice<PackageInfo>(list); 5448 } 5449 } 5450 5451 @Override 5452 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 5453 if (!sUserManager.exists(userId)) return null; 5454 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5455 5456 // writer 5457 synchronized (mPackages) { 5458 ArrayList<ApplicationInfo> list; 5459 if (listUninstalled) { 5460 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 5461 for (PackageSetting ps : mSettings.mPackages.values()) { 5462 ApplicationInfo ai; 5463 if (ps.pkg != null) { 5464 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 5465 ps.readUserState(userId), userId); 5466 } else { 5467 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 5468 } 5469 if (ai != null) { 5470 list.add(ai); 5471 } 5472 } 5473 } else { 5474 list = new ArrayList<ApplicationInfo>(mPackages.size()); 5475 for (PackageParser.Package p : mPackages.values()) { 5476 if (p.mExtras != null) { 5477 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5478 ((PackageSetting)p.mExtras).readUserState(userId), userId); 5479 if (ai != null) { 5480 list.add(ai); 5481 } 5482 } 5483 } 5484 } 5485 5486 return new ParceledListSlice<ApplicationInfo>(list); 5487 } 5488 } 5489 5490 public List<ApplicationInfo> getPersistentApplications(int flags) { 5491 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 5492 5493 // reader 5494 synchronized (mPackages) { 5495 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 5496 final int userId = UserHandle.getCallingUserId(); 5497 while (i.hasNext()) { 5498 final PackageParser.Package p = i.next(); 5499 if (p.applicationInfo != null 5500 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 5501 && (!mSafeMode || isSystemApp(p))) { 5502 PackageSetting ps = mSettings.mPackages.get(p.packageName); 5503 if (ps != null) { 5504 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5505 ps.readUserState(userId), userId); 5506 if (ai != null) { 5507 finalList.add(ai); 5508 } 5509 } 5510 } 5511 } 5512 } 5513 5514 return finalList; 5515 } 5516 5517 @Override 5518 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 5519 if (!sUserManager.exists(userId)) return null; 5520 // reader 5521 synchronized (mPackages) { 5522 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 5523 PackageSetting ps = provider != null 5524 ? mSettings.mPackages.get(provider.owner.packageName) 5525 : null; 5526 return ps != null 5527 && mSettings.isEnabledLPr(provider.info, flags, userId) 5528 && (!mSafeMode || (provider.info.applicationInfo.flags 5529 &ApplicationInfo.FLAG_SYSTEM) != 0) 5530 ? PackageParser.generateProviderInfo(provider, flags, 5531 ps.readUserState(userId), userId) 5532 : null; 5533 } 5534 } 5535 5536 /** 5537 * @deprecated 5538 */ 5539 @Deprecated 5540 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 5541 // reader 5542 synchronized (mPackages) { 5543 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 5544 .entrySet().iterator(); 5545 final int userId = UserHandle.getCallingUserId(); 5546 while (i.hasNext()) { 5547 Map.Entry<String, PackageParser.Provider> entry = i.next(); 5548 PackageParser.Provider p = entry.getValue(); 5549 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 5550 5551 if (ps != null && p.syncable 5552 && (!mSafeMode || (p.info.applicationInfo.flags 5553 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 5554 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 5555 ps.readUserState(userId), userId); 5556 if (info != null) { 5557 outNames.add(entry.getKey()); 5558 outInfo.add(info); 5559 } 5560 } 5561 } 5562 } 5563 } 5564 5565 @Override 5566 public ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 5567 int uid, int flags) { 5568 ArrayList<ProviderInfo> finalList = null; 5569 // reader 5570 synchronized (mPackages) { 5571 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 5572 final int userId = processName != null ? 5573 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 5574 while (i.hasNext()) { 5575 final PackageParser.Provider p = i.next(); 5576 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 5577 if (ps != null && p.info.authority != null 5578 && (processName == null 5579 || (p.info.processName.equals(processName) 5580 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 5581 && mSettings.isEnabledLPr(p.info, flags, userId) 5582 && (!mSafeMode 5583 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 5584 if (finalList == null) { 5585 finalList = new ArrayList<ProviderInfo>(3); 5586 } 5587 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 5588 ps.readUserState(userId), userId); 5589 if (info != null) { 5590 finalList.add(info); 5591 } 5592 } 5593 } 5594 } 5595 5596 if (finalList != null) { 5597 Collections.sort(finalList, mProviderInitOrderSorter); 5598 return new ParceledListSlice<ProviderInfo>(finalList); 5599 } 5600 5601 return null; 5602 } 5603 5604 @Override 5605 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 5606 int flags) { 5607 // reader 5608 synchronized (mPackages) { 5609 final PackageParser.Instrumentation i = mInstrumentation.get(name); 5610 return PackageParser.generateInstrumentationInfo(i, flags); 5611 } 5612 } 5613 5614 @Override 5615 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 5616 int flags) { 5617 ArrayList<InstrumentationInfo> finalList = 5618 new ArrayList<InstrumentationInfo>(); 5619 5620 // reader 5621 synchronized (mPackages) { 5622 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 5623 while (i.hasNext()) { 5624 final PackageParser.Instrumentation p = i.next(); 5625 if (targetPackage == null 5626 || targetPackage.equals(p.info.targetPackage)) { 5627 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 5628 flags); 5629 if (ii != null) { 5630 finalList.add(ii); 5631 } 5632 } 5633 } 5634 } 5635 5636 return finalList; 5637 } 5638 5639 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 5640 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 5641 if (overlays == null) { 5642 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 5643 return; 5644 } 5645 for (PackageParser.Package opkg : overlays.values()) { 5646 // Not much to do if idmap fails: we already logged the error 5647 // and we certainly don't want to abort installation of pkg simply 5648 // because an overlay didn't fit properly. For these reasons, 5649 // ignore the return value of createIdmapForPackagePairLI. 5650 createIdmapForPackagePairLI(pkg, opkg); 5651 } 5652 } 5653 5654 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 5655 PackageParser.Package opkg) { 5656 if (!opkg.mTrustedOverlay) { 5657 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 5658 opkg.baseCodePath + ": overlay not trusted"); 5659 return false; 5660 } 5661 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 5662 if (overlaySet == null) { 5663 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 5664 opkg.baseCodePath + " but target package has no known overlays"); 5665 return false; 5666 } 5667 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 5668 // TODO: generate idmap for split APKs 5669 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 5670 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 5671 + opkg.baseCodePath); 5672 return false; 5673 } 5674 PackageParser.Package[] overlayArray = 5675 overlaySet.values().toArray(new PackageParser.Package[0]); 5676 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 5677 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 5678 return p1.mOverlayPriority - p2.mOverlayPriority; 5679 } 5680 }; 5681 Arrays.sort(overlayArray, cmp); 5682 5683 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 5684 int i = 0; 5685 for (PackageParser.Package p : overlayArray) { 5686 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 5687 } 5688 return true; 5689 } 5690 5691 private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) { 5692 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 5693 try { 5694 scanDirLI(dir, parseFlags, scanFlags, currentTime); 5695 } finally { 5696 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5697 } 5698 } 5699 5700 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 5701 final File[] files = dir.listFiles(); 5702 if (ArrayUtils.isEmpty(files)) { 5703 Log.d(TAG, "No files in app dir " + dir); 5704 return; 5705 } 5706 5707 if (DEBUG_PACKAGE_SCANNING) { 5708 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 5709 + " flags=0x" + Integer.toHexString(parseFlags)); 5710 } 5711 5712 for (File file : files) { 5713 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 5714 && !PackageInstallerService.isStageName(file.getName()); 5715 if (!isPackage) { 5716 // Ignore entries which are not packages 5717 continue; 5718 } 5719 try { 5720 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 5721 scanFlags, currentTime, null); 5722 } catch (PackageManagerException e) { 5723 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 5724 5725 // Delete invalid userdata apps 5726 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 5727 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 5728 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 5729 if (file.isDirectory()) { 5730 mInstaller.rmPackageDir(file.getAbsolutePath()); 5731 } else { 5732 file.delete(); 5733 } 5734 } 5735 } 5736 } 5737 } 5738 5739 private static File getSettingsProblemFile() { 5740 File dataDir = Environment.getDataDirectory(); 5741 File systemDir = new File(dataDir, "system"); 5742 File fname = new File(systemDir, "uiderrors.txt"); 5743 return fname; 5744 } 5745 5746 static void reportSettingsProblem(int priority, String msg) { 5747 logCriticalInfo(priority, msg); 5748 } 5749 5750 static void logCriticalInfo(int priority, String msg) { 5751 Slog.println(priority, TAG, msg); 5752 EventLogTags.writePmCriticalInfo(msg); 5753 try { 5754 File fname = getSettingsProblemFile(); 5755 FileOutputStream out = new FileOutputStream(fname, true); 5756 PrintWriter pw = new FastPrintWriter(out); 5757 SimpleDateFormat formatter = new SimpleDateFormat(); 5758 String dateString = formatter.format(new Date(System.currentTimeMillis())); 5759 pw.println(dateString + ": " + msg); 5760 pw.close(); 5761 FileUtils.setPermissions( 5762 fname.toString(), 5763 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 5764 -1, -1); 5765 } catch (java.io.IOException e) { 5766 } 5767 } 5768 5769 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 5770 PackageParser.Package pkg, File srcFile, int parseFlags) 5771 throws PackageManagerException { 5772 if (ps != null 5773 && ps.codePath.equals(srcFile) 5774 && ps.timeStamp == srcFile.lastModified() 5775 && !isCompatSignatureUpdateNeeded(pkg) 5776 && !isRecoverSignatureUpdateNeeded(pkg)) { 5777 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 5778 KeySetManagerService ksms = mSettings.mKeySetManagerService; 5779 ArraySet<PublicKey> signingKs; 5780 synchronized (mPackages) { 5781 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 5782 } 5783 if (ps.signatures.mSignatures != null 5784 && ps.signatures.mSignatures.length != 0 5785 && signingKs != null) { 5786 // Optimization: reuse the existing cached certificates 5787 // if the package appears to be unchanged. 5788 pkg.mSignatures = ps.signatures.mSignatures; 5789 pkg.mSigningKeys = signingKs; 5790 return; 5791 } 5792 5793 Slog.w(TAG, "PackageSetting for " + ps.name 5794 + " is missing signatures. Collecting certs again to recover them."); 5795 } else { 5796 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 5797 } 5798 5799 try { 5800 pp.collectCertificates(pkg, parseFlags); 5801 pp.collectManifestDigest(pkg); 5802 } catch (PackageParserException e) { 5803 throw PackageManagerException.from(e); 5804 } 5805 } 5806 5807 /** 5808 * Traces a package scan. 5809 * @see #scanPackageLI(File, int, int, long, UserHandle) 5810 */ 5811 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 5812 long currentTime, UserHandle user) throws PackageManagerException { 5813 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 5814 try { 5815 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 5816 } finally { 5817 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5818 } 5819 } 5820 5821 /** 5822 * Scans a package and returns the newly parsed package. 5823 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 5824 */ 5825 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 5826 long currentTime, UserHandle user) throws PackageManagerException { 5827 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 5828 parseFlags |= mDefParseFlags; 5829 PackageParser pp = new PackageParser(); 5830 pp.setSeparateProcesses(mSeparateProcesses); 5831 pp.setOnlyCoreApps(mOnlyCore); 5832 pp.setDisplayMetrics(mMetrics); 5833 5834 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 5835 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 5836 } 5837 5838 final PackageParser.Package pkg; 5839 try { 5840 pkg = pp.parsePackage(scanFile, parseFlags); 5841 } catch (PackageParserException e) { 5842 throw PackageManagerException.from(e); 5843 } 5844 5845 PackageSetting ps = null; 5846 PackageSetting updatedPkg; 5847 // reader 5848 synchronized (mPackages) { 5849 // Look to see if we already know about this package. 5850 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 5851 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 5852 // This package has been renamed to its original name. Let's 5853 // use that. 5854 ps = mSettings.peekPackageLPr(oldName); 5855 } 5856 // If there was no original package, see one for the real package name. 5857 if (ps == null) { 5858 ps = mSettings.peekPackageLPr(pkg.packageName); 5859 } 5860 // Check to see if this package could be hiding/updating a system 5861 // package. Must look for it either under the original or real 5862 // package name depending on our state. 5863 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 5864 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 5865 } 5866 boolean updatedPkgBetter = false; 5867 // First check if this is a system package that may involve an update 5868 if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 5869 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 5870 // it needs to drop FLAG_PRIVILEGED. 5871 if (locationIsPrivileged(scanFile)) { 5872 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5873 } else { 5874 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5875 } 5876 5877 if (ps != null && !ps.codePath.equals(scanFile)) { 5878 // The path has changed from what was last scanned... check the 5879 // version of the new path against what we have stored to determine 5880 // what to do. 5881 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 5882 if (pkg.mVersionCode <= ps.versionCode) { 5883 // The system package has been updated and the code path does not match 5884 // Ignore entry. Skip it. 5885 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 5886 + " ignored: updated version " + ps.versionCode 5887 + " better than this " + pkg.mVersionCode); 5888 if (!updatedPkg.codePath.equals(scanFile)) { 5889 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 5890 + ps.name + " changing from " + updatedPkg.codePathString 5891 + " to " + scanFile); 5892 updatedPkg.codePath = scanFile; 5893 updatedPkg.codePathString = scanFile.toString(); 5894 updatedPkg.resourcePath = scanFile; 5895 updatedPkg.resourcePathString = scanFile.toString(); 5896 } 5897 updatedPkg.pkg = pkg; 5898 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5899 "Package " + ps.name + " at " + scanFile 5900 + " ignored: updated version " + ps.versionCode 5901 + " better than this " + pkg.mVersionCode); 5902 } else { 5903 // The current app on the system partition is better than 5904 // what we have updated to on the data partition; switch 5905 // back to the system partition version. 5906 // At this point, its safely assumed that package installation for 5907 // apps in system partition will go through. If not there won't be a working 5908 // version of the app 5909 // writer 5910 synchronized (mPackages) { 5911 // Just remove the loaded entries from package lists. 5912 mPackages.remove(ps.name); 5913 } 5914 5915 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5916 + " reverting from " + ps.codePathString 5917 + ": new version " + pkg.mVersionCode 5918 + " better than installed " + ps.versionCode); 5919 5920 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5921 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5922 synchronized (mInstallLock) { 5923 args.cleanUpResourcesLI(); 5924 } 5925 synchronized (mPackages) { 5926 mSettings.enableSystemPackageLPw(ps.name); 5927 } 5928 updatedPkgBetter = true; 5929 } 5930 } 5931 } 5932 5933 if (updatedPkg != null) { 5934 // An updated system app will not have the PARSE_IS_SYSTEM flag set 5935 // initially 5936 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 5937 5938 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 5939 // flag set initially 5940 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 5941 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 5942 } 5943 } 5944 5945 // Verify certificates against what was last scanned 5946 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 5947 5948 /* 5949 * A new system app appeared, but we already had a non-system one of the 5950 * same name installed earlier. 5951 */ 5952 boolean shouldHideSystemApp = false; 5953 if (updatedPkg == null && ps != null 5954 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 5955 /* 5956 * Check to make sure the signatures match first. If they don't, 5957 * wipe the installed application and its data. 5958 */ 5959 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 5960 != PackageManager.SIGNATURE_MATCH) { 5961 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 5962 + " signatures don't match existing userdata copy; removing"); 5963 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 5964 ps = null; 5965 } else { 5966 /* 5967 * If the newly-added system app is an older version than the 5968 * already installed version, hide it. It will be scanned later 5969 * and re-added like an update. 5970 */ 5971 if (pkg.mVersionCode <= ps.versionCode) { 5972 shouldHideSystemApp = true; 5973 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 5974 + " but new version " + pkg.mVersionCode + " better than installed " 5975 + ps.versionCode + "; hiding system"); 5976 } else { 5977 /* 5978 * The newly found system app is a newer version that the 5979 * one previously installed. Simply remove the 5980 * already-installed application and replace it with our own 5981 * while keeping the application data. 5982 */ 5983 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5984 + " reverting from " + ps.codePathString + ": new version " 5985 + pkg.mVersionCode + " better than installed " + ps.versionCode); 5986 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5987 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5988 synchronized (mInstallLock) { 5989 args.cleanUpResourcesLI(); 5990 } 5991 } 5992 } 5993 } 5994 5995 // The apk is forward locked (not public) if its code and resources 5996 // are kept in different files. (except for app in either system or 5997 // vendor path). 5998 // TODO grab this value from PackageSettings 5999 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6000 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6001 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 6002 } 6003 } 6004 6005 // TODO: extend to support forward-locked splits 6006 String resourcePath = null; 6007 String baseResourcePath = null; 6008 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6009 if (ps != null && ps.resourcePathString != null) { 6010 resourcePath = ps.resourcePathString; 6011 baseResourcePath = ps.resourcePathString; 6012 } else { 6013 // Should not happen at all. Just log an error. 6014 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 6015 } 6016 } else { 6017 resourcePath = pkg.codePath; 6018 baseResourcePath = pkg.baseCodePath; 6019 } 6020 6021 // Set application objects path explicitly. 6022 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 6023 pkg.applicationInfo.setCodePath(pkg.codePath); 6024 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 6025 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 6026 pkg.applicationInfo.setResourcePath(resourcePath); 6027 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 6028 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 6029 6030 // Note that we invoke the following method only if we are about to unpack an application 6031 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 6032 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6033 6034 /* 6035 * If the system app should be overridden by a previously installed 6036 * data, hide the system app now and let the /data/app scan pick it up 6037 * again. 6038 */ 6039 if (shouldHideSystemApp) { 6040 synchronized (mPackages) { 6041 mSettings.disableSystemPackageLPw(pkg.packageName); 6042 } 6043 } 6044 6045 return scannedPkg; 6046 } 6047 6048 private static String fixProcessName(String defProcessName, 6049 String processName, int uid) { 6050 if (processName == null) { 6051 return defProcessName; 6052 } 6053 return processName; 6054 } 6055 6056 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 6057 throws PackageManagerException { 6058 if (pkgSetting.signatures.mSignatures != null) { 6059 // Already existing package. Make sure signatures match 6060 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 6061 == PackageManager.SIGNATURE_MATCH; 6062 if (!match) { 6063 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 6064 == PackageManager.SIGNATURE_MATCH; 6065 } 6066 if (!match) { 6067 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 6068 == PackageManager.SIGNATURE_MATCH; 6069 } 6070 if (!match) { 6071 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6072 + pkg.packageName + " signatures do not match the " 6073 + "previously installed version; ignoring!"); 6074 } 6075 } 6076 6077 // Check for shared user signatures 6078 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 6079 // Already existing package. Make sure signatures match 6080 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6081 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 6082 if (!match) { 6083 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 6084 == PackageManager.SIGNATURE_MATCH; 6085 } 6086 if (!match) { 6087 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 6088 == PackageManager.SIGNATURE_MATCH; 6089 } 6090 if (!match) { 6091 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6092 "Package " + pkg.packageName 6093 + " has no signatures that match those in shared user " 6094 + pkgSetting.sharedUser.name + "; ignoring!"); 6095 } 6096 } 6097 } 6098 6099 /** 6100 * Enforces that only the system UID or root's UID can call a method exposed 6101 * via Binder. 6102 * 6103 * @param message used as message if SecurityException is thrown 6104 * @throws SecurityException if the caller is not system or root 6105 */ 6106 private static final void enforceSystemOrRoot(String message) { 6107 final int uid = Binder.getCallingUid(); 6108 if (uid != Process.SYSTEM_UID && uid != 0) { 6109 throw new SecurityException(message); 6110 } 6111 } 6112 6113 @Override 6114 public void performBootDexOpt() { 6115 enforceSystemOrRoot("Only the system can request dexopt be performed"); 6116 6117 // Before everything else, see whether we need to fstrim. 6118 try { 6119 IMountService ms = PackageHelper.getMountService(); 6120 if (ms != null) { 6121 final boolean isUpgrade = isUpgrade(); 6122 boolean doTrim = isUpgrade; 6123 if (doTrim) { 6124 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6125 } else { 6126 final long interval = android.provider.Settings.Global.getLong( 6127 mContext.getContentResolver(), 6128 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6129 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6130 if (interval > 0) { 6131 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6132 if (timeSinceLast > interval) { 6133 doTrim = true; 6134 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6135 + "; running immediately"); 6136 } 6137 } 6138 } 6139 if (doTrim) { 6140 if (!isFirstBoot()) { 6141 try { 6142 ActivityManagerNative.getDefault().showBootMessage( 6143 mContext.getResources().getString( 6144 R.string.android_upgrading_fstrim), true); 6145 } catch (RemoteException e) { 6146 } 6147 } 6148 ms.runMaintenance(); 6149 } 6150 } else { 6151 Slog.e(TAG, "Mount service unavailable!"); 6152 } 6153 } catch (RemoteException e) { 6154 // Can't happen; MountService is local 6155 } 6156 6157 final ArraySet<PackageParser.Package> pkgs; 6158 synchronized (mPackages) { 6159 pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages(); 6160 } 6161 6162 if (pkgs != null) { 6163 // Sort apps by importance for dexopt ordering. Important apps are given more priority 6164 // in case the device runs out of space. 6165 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 6166 // Give priority to core apps. 6167 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6168 PackageParser.Package pkg = it.next(); 6169 if (pkg.coreApp) { 6170 if (DEBUG_DEXOPT) { 6171 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 6172 } 6173 sortedPkgs.add(pkg); 6174 it.remove(); 6175 } 6176 } 6177 // Give priority to system apps that listen for pre boot complete. 6178 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 6179 ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM); 6180 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6181 PackageParser.Package pkg = it.next(); 6182 if (pkgNames.contains(pkg.packageName)) { 6183 if (DEBUG_DEXOPT) { 6184 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 6185 } 6186 sortedPkgs.add(pkg); 6187 it.remove(); 6188 } 6189 } 6190 // Filter out packages that aren't recently used. 6191 filterRecentlyUsedApps(pkgs); 6192 // Add all remaining apps. 6193 for (PackageParser.Package pkg : pkgs) { 6194 if (DEBUG_DEXOPT) { 6195 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 6196 } 6197 sortedPkgs.add(pkg); 6198 } 6199 6200 // If we want to be lazy, filter everything that wasn't recently used. 6201 if (mLazyDexOpt) { 6202 filterRecentlyUsedApps(sortedPkgs); 6203 } 6204 6205 int i = 0; 6206 int total = sortedPkgs.size(); 6207 File dataDir = Environment.getDataDirectory(); 6208 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 6209 if (lowThreshold == 0) { 6210 throw new IllegalStateException("Invalid low memory threshold"); 6211 } 6212 for (PackageParser.Package pkg : sortedPkgs) { 6213 long usableSpace = dataDir.getUsableSpace(); 6214 if (usableSpace < lowThreshold) { 6215 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 6216 break; 6217 } 6218 performBootDexOpt(pkg, ++i, total); 6219 } 6220 } 6221 } 6222 6223 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 6224 // Filter out packages that aren't recently used. 6225 // 6226 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 6227 // should do a full dexopt. 6228 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 6229 int total = pkgs.size(); 6230 int skipped = 0; 6231 long now = System.currentTimeMillis(); 6232 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 6233 PackageParser.Package pkg = i.next(); 6234 long then = pkg.mLastPackageUsageTimeInMills; 6235 if (then + mDexOptLRUThresholdInMills < now) { 6236 if (DEBUG_DEXOPT) { 6237 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 6238 ((then == 0) ? "never" : new Date(then))); 6239 } 6240 i.remove(); 6241 skipped++; 6242 } 6243 } 6244 if (DEBUG_DEXOPT) { 6245 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 6246 } 6247 } 6248 } 6249 6250 private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) { 6251 List<ResolveInfo> ris = null; 6252 try { 6253 ris = AppGlobals.getPackageManager().queryIntentReceivers( 6254 intent, null, 0, userId); 6255 } catch (RemoteException e) { 6256 } 6257 ArraySet<String> pkgNames = new ArraySet<String>(); 6258 if (ris != null) { 6259 for (ResolveInfo ri : ris) { 6260 pkgNames.add(ri.activityInfo.packageName); 6261 } 6262 } 6263 return pkgNames; 6264 } 6265 6266 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 6267 if (DEBUG_DEXOPT) { 6268 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 6269 } 6270 if (!isFirstBoot()) { 6271 try { 6272 ActivityManagerNative.getDefault().showBootMessage( 6273 mContext.getResources().getString(R.string.android_upgrading_apk, 6274 curr, total), true); 6275 } catch (RemoteException e) { 6276 } 6277 } 6278 PackageParser.Package p = pkg; 6279 synchronized (mInstallLock) { 6280 mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, 6281 false /* force dex */, false /* defer */, true /* include dependencies */, 6282 false /* boot complete */, false /*useJit*/); 6283 } 6284 } 6285 6286 @Override 6287 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6288 return performDexOptTraced(packageName, instructionSet, false); 6289 } 6290 6291 public boolean performDexOpt( 6292 String packageName, String instructionSet, boolean backgroundDexopt) { 6293 return performDexOptTraced(packageName, instructionSet, backgroundDexopt); 6294 } 6295 6296 private boolean performDexOptTraced( 6297 String packageName, String instructionSet, boolean backgroundDexopt) { 6298 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 6299 try { 6300 return performDexOptInternal(packageName, instructionSet, backgroundDexopt); 6301 } finally { 6302 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6303 } 6304 } 6305 6306 private boolean performDexOptInternal( 6307 String packageName, String instructionSet, boolean backgroundDexopt) { 6308 boolean dexopt = mLazyDexOpt || backgroundDexopt; 6309 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 6310 if (!dexopt && !updateUsage) { 6311 // We aren't going to dexopt or update usage, so bail early. 6312 return false; 6313 } 6314 PackageParser.Package p; 6315 final String targetInstructionSet; 6316 synchronized (mPackages) { 6317 p = mPackages.get(packageName); 6318 if (p == null) { 6319 return false; 6320 } 6321 if (updateUsage) { 6322 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6323 } 6324 mPackageUsage.write(false); 6325 if (!dexopt) { 6326 // We aren't going to dexopt, so bail early. 6327 return false; 6328 } 6329 6330 targetInstructionSet = instructionSet != null ? instructionSet : 6331 getPrimaryInstructionSet(p.applicationInfo); 6332 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 6333 return false; 6334 } 6335 } 6336 long callingId = Binder.clearCallingIdentity(); 6337 try { 6338 synchronized (mInstallLock) { 6339 final String[] instructionSets = new String[] { targetInstructionSet }; 6340 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, 6341 false /* forceDex */, false /* defer */, true /* inclDependencies */, 6342 true /* boot complete */, false /*useJit*/); 6343 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 6344 } 6345 } finally { 6346 Binder.restoreCallingIdentity(callingId); 6347 } 6348 } 6349 6350 public ArraySet<String> getPackagesThatNeedDexOpt() { 6351 ArraySet<String> pkgs = null; 6352 synchronized (mPackages) { 6353 for (PackageParser.Package p : mPackages.values()) { 6354 if (DEBUG_DEXOPT) { 6355 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 6356 } 6357 if (!p.mDexOptPerformed.isEmpty()) { 6358 continue; 6359 } 6360 if (pkgs == null) { 6361 pkgs = new ArraySet<String>(); 6362 } 6363 pkgs.add(p.packageName); 6364 } 6365 } 6366 return pkgs; 6367 } 6368 6369 public void shutdown() { 6370 mPackageUsage.write(true); 6371 } 6372 6373 @Override 6374 public void forceDexOpt(String packageName) { 6375 enforceSystemOrRoot("forceDexOpt"); 6376 6377 PackageParser.Package pkg; 6378 synchronized (mPackages) { 6379 pkg = mPackages.get(packageName); 6380 if (pkg == null) { 6381 throw new IllegalArgumentException("Missing package: " + packageName); 6382 } 6383 } 6384 6385 synchronized (mInstallLock) { 6386 final String[] instructionSets = new String[] { 6387 getPrimaryInstructionSet(pkg.applicationInfo) }; 6388 6389 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 6390 6391 final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, 6392 true /*forceDex*/, false /* defer */, true /* inclDependencies */, 6393 true /* boot complete */, false /*useJit*/); 6394 6395 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6396 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 6397 throw new IllegalStateException("Failed to dexopt: " + res); 6398 } 6399 } 6400 } 6401 6402 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 6403 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6404 Slog.w(TAG, "Unable to update from " + oldPkg.name 6405 + " to " + newPkg.packageName 6406 + ": old package not in system partition"); 6407 return false; 6408 } else if (mPackages.get(oldPkg.name) != null) { 6409 Slog.w(TAG, "Unable to update from " + oldPkg.name 6410 + " to " + newPkg.packageName 6411 + ": old package still exists"); 6412 return false; 6413 } 6414 return true; 6415 } 6416 6417 private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) { 6418 int[] users = sUserManager.getUserIds(); 6419 int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo); 6420 if (res < 0) { 6421 return res; 6422 } 6423 for (int user : users) { 6424 if (user != 0) { 6425 res = mInstaller.createUserData(volumeUuid, packageName, 6426 UserHandle.getUid(user, uid), user, seinfo); 6427 if (res < 0) { 6428 return res; 6429 } 6430 } 6431 } 6432 return res; 6433 } 6434 6435 private int removeDataDirsLI(String volumeUuid, String packageName) { 6436 int[] users = sUserManager.getUserIds(); 6437 int res = 0; 6438 for (int user : users) { 6439 int resInner = mInstaller.remove(volumeUuid, packageName, user); 6440 if (resInner < 0) { 6441 res = resInner; 6442 } 6443 } 6444 6445 return res; 6446 } 6447 6448 private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 6449 int[] users = sUserManager.getUserIds(); 6450 int res = 0; 6451 for (int user : users) { 6452 int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user); 6453 if (resInner < 0) { 6454 res = resInner; 6455 } 6456 } 6457 return res; 6458 } 6459 6460 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 6461 PackageParser.Package changingLib) { 6462 if (file.path != null) { 6463 usesLibraryFiles.add(file.path); 6464 return; 6465 } 6466 PackageParser.Package p = mPackages.get(file.apk); 6467 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 6468 // If we are doing this while in the middle of updating a library apk, 6469 // then we need to make sure to use that new apk for determining the 6470 // dependencies here. (We haven't yet finished committing the new apk 6471 // to the package manager state.) 6472 if (p == null || p.packageName.equals(changingLib.packageName)) { 6473 p = changingLib; 6474 } 6475 } 6476 if (p != null) { 6477 usesLibraryFiles.addAll(p.getAllCodePaths()); 6478 } 6479 } 6480 6481 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 6482 PackageParser.Package changingLib) throws PackageManagerException { 6483 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 6484 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 6485 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 6486 for (int i=0; i<N; i++) { 6487 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 6488 if (file == null) { 6489 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 6490 "Package " + pkg.packageName + " requires unavailable shared library " 6491 + pkg.usesLibraries.get(i) + "; failing!"); 6492 } 6493 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 6494 } 6495 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 6496 for (int i=0; i<N; i++) { 6497 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 6498 if (file == null) { 6499 Slog.w(TAG, "Package " + pkg.packageName 6500 + " desires unavailable shared library " 6501 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 6502 } else { 6503 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 6504 } 6505 } 6506 N = usesLibraryFiles.size(); 6507 if (N > 0) { 6508 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 6509 } else { 6510 pkg.usesLibraryFiles = null; 6511 } 6512 } 6513 } 6514 6515 private static boolean hasString(List<String> list, List<String> which) { 6516 if (list == null) { 6517 return false; 6518 } 6519 for (int i=list.size()-1; i>=0; i--) { 6520 for (int j=which.size()-1; j>=0; j--) { 6521 if (which.get(j).equals(list.get(i))) { 6522 return true; 6523 } 6524 } 6525 } 6526 return false; 6527 } 6528 6529 private void updateAllSharedLibrariesLPw() { 6530 for (PackageParser.Package pkg : mPackages.values()) { 6531 try { 6532 updateSharedLibrariesLPw(pkg, null); 6533 } catch (PackageManagerException e) { 6534 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 6535 } 6536 } 6537 } 6538 6539 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 6540 PackageParser.Package changingPkg) { 6541 ArrayList<PackageParser.Package> res = null; 6542 for (PackageParser.Package pkg : mPackages.values()) { 6543 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 6544 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 6545 if (res == null) { 6546 res = new ArrayList<PackageParser.Package>(); 6547 } 6548 res.add(pkg); 6549 try { 6550 updateSharedLibrariesLPw(pkg, changingPkg); 6551 } catch (PackageManagerException e) { 6552 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 6553 } 6554 } 6555 } 6556 return res; 6557 } 6558 6559 /** 6560 * Derive the value of the {@code cpuAbiOverride} based on the provided 6561 * value and an optional stored value from the package settings. 6562 */ 6563 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 6564 String cpuAbiOverride = null; 6565 6566 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 6567 cpuAbiOverride = null; 6568 } else if (abiOverride != null) { 6569 cpuAbiOverride = abiOverride; 6570 } else if (settings != null) { 6571 cpuAbiOverride = settings.cpuAbiOverrideString; 6572 } 6573 6574 return cpuAbiOverride; 6575 } 6576 6577 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 6578 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6579 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6580 try { 6581 return scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 6582 } finally { 6583 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6584 } 6585 } 6586 6587 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 6588 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6589 boolean success = false; 6590 try { 6591 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 6592 currentTime, user); 6593 success = true; 6594 return res; 6595 } finally { 6596 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 6597 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 6598 } 6599 } 6600 } 6601 6602 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 6603 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6604 final File scanFile = new File(pkg.codePath); 6605 if (pkg.applicationInfo.getCodePath() == null || 6606 pkg.applicationInfo.getResourcePath() == null) { 6607 // Bail out. The resource and code paths haven't been set. 6608 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 6609 "Code and resource paths haven't been set correctly"); 6610 } 6611 6612 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 6613 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 6614 } else { 6615 // Only allow system apps to be flagged as core apps. 6616 pkg.coreApp = false; 6617 } 6618 6619 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 6620 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6621 } 6622 6623 if (mCustomResolverComponentName != null && 6624 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 6625 setUpCustomResolverActivity(pkg); 6626 } 6627 6628 if (pkg.packageName.equals("android")) { 6629 synchronized (mPackages) { 6630 if (mAndroidApplication != null) { 6631 Slog.w(TAG, "*************************************************"); 6632 Slog.w(TAG, "Core android package being redefined. Skipping."); 6633 Slog.w(TAG, " file=" + scanFile); 6634 Slog.w(TAG, "*************************************************"); 6635 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 6636 "Core android package being redefined. Skipping."); 6637 } 6638 6639 // Set up information for our fall-back user intent resolution activity. 6640 mPlatformPackage = pkg; 6641 pkg.mVersionCode = mSdkVersion; 6642 mAndroidApplication = pkg.applicationInfo; 6643 6644 if (!mResolverReplaced) { 6645 mResolveActivity.applicationInfo = mAndroidApplication; 6646 mResolveActivity.name = ResolverActivity.class.getName(); 6647 mResolveActivity.packageName = mAndroidApplication.packageName; 6648 mResolveActivity.processName = "system:ui"; 6649 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6650 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 6651 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 6652 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 6653 mResolveActivity.exported = true; 6654 mResolveActivity.enabled = true; 6655 mResolveInfo.activityInfo = mResolveActivity; 6656 mResolveInfo.priority = 0; 6657 mResolveInfo.preferredOrder = 0; 6658 mResolveInfo.match = 0; 6659 mResolveComponentName = new ComponentName( 6660 mAndroidApplication.packageName, mResolveActivity.name); 6661 } 6662 } 6663 } 6664 6665 if (DEBUG_PACKAGE_SCANNING) { 6666 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6667 Log.d(TAG, "Scanning package " + pkg.packageName); 6668 } 6669 6670 if (mPackages.containsKey(pkg.packageName) 6671 || mSharedLibraries.containsKey(pkg.packageName)) { 6672 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 6673 "Application package " + pkg.packageName 6674 + " already installed. Skipping duplicate."); 6675 } 6676 6677 // If we're only installing presumed-existing packages, require that the 6678 // scanned APK is both already known and at the path previously established 6679 // for it. Previously unknown packages we pick up normally, but if we have an 6680 // a priori expectation about this package's install presence, enforce it. 6681 // With a singular exception for new system packages. When an OTA contains 6682 // a new system package, we allow the codepath to change from a system location 6683 // to the user-installed location. If we don't allow this change, any newer, 6684 // user-installed version of the application will be ignored. 6685 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 6686 if (mExpectingBetter.containsKey(pkg.packageName)) { 6687 logCriticalInfo(Log.WARN, 6688 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 6689 } else { 6690 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 6691 if (known != null) { 6692 if (DEBUG_PACKAGE_SCANNING) { 6693 Log.d(TAG, "Examining " + pkg.codePath 6694 + " and requiring known paths " + known.codePathString 6695 + " & " + known.resourcePathString); 6696 } 6697 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 6698 || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { 6699 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 6700 "Application package " + pkg.packageName 6701 + " found at " + pkg.applicationInfo.getCodePath() 6702 + " but expected at " + known.codePathString + "; ignoring."); 6703 } 6704 } 6705 } 6706 } 6707 6708 // Initialize package source and resource directories 6709 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 6710 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 6711 6712 SharedUserSetting suid = null; 6713 PackageSetting pkgSetting = null; 6714 6715 if (!isSystemApp(pkg)) { 6716 // Only system apps can use these features. 6717 pkg.mOriginalPackages = null; 6718 pkg.mRealPackage = null; 6719 pkg.mAdoptPermissions = null; 6720 } 6721 6722 // writer 6723 synchronized (mPackages) { 6724 if (pkg.mSharedUserId != null) { 6725 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 6726 if (suid == null) { 6727 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6728 "Creating application package " + pkg.packageName 6729 + " for shared user failed"); 6730 } 6731 if (DEBUG_PACKAGE_SCANNING) { 6732 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6733 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 6734 + "): packages=" + suid.packages); 6735 } 6736 } 6737 6738 // Check if we are renaming from an original package name. 6739 PackageSetting origPackage = null; 6740 String realName = null; 6741 if (pkg.mOriginalPackages != null) { 6742 // This package may need to be renamed to a previously 6743 // installed name. Let's check on that... 6744 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 6745 if (pkg.mOriginalPackages.contains(renamed)) { 6746 // This package had originally been installed as the 6747 // original name, and we have already taken care of 6748 // transitioning to the new one. Just update the new 6749 // one to continue using the old name. 6750 realName = pkg.mRealPackage; 6751 if (!pkg.packageName.equals(renamed)) { 6752 // Callers into this function may have already taken 6753 // care of renaming the package; only do it here if 6754 // it is not already done. 6755 pkg.setPackageName(renamed); 6756 } 6757 6758 } else { 6759 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 6760 if ((origPackage = mSettings.peekPackageLPr( 6761 pkg.mOriginalPackages.get(i))) != null) { 6762 // We do have the package already installed under its 6763 // original name... should we use it? 6764 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 6765 // New package is not compatible with original. 6766 origPackage = null; 6767 continue; 6768 } else if (origPackage.sharedUser != null) { 6769 // Make sure uid is compatible between packages. 6770 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 6771 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 6772 + " to " + pkg.packageName + ": old uid " 6773 + origPackage.sharedUser.name 6774 + " differs from " + pkg.mSharedUserId); 6775 origPackage = null; 6776 continue; 6777 } 6778 } else { 6779 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 6780 + pkg.packageName + " to old name " + origPackage.name); 6781 } 6782 break; 6783 } 6784 } 6785 } 6786 } 6787 6788 if (mTransferedPackages.contains(pkg.packageName)) { 6789 Slog.w(TAG, "Package " + pkg.packageName 6790 + " was transferred to another, but its .apk remains"); 6791 } 6792 6793 // Just create the setting, don't add it yet. For already existing packages 6794 // the PkgSetting exists already and doesn't have to be created. 6795 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 6796 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 6797 pkg.applicationInfo.primaryCpuAbi, 6798 pkg.applicationInfo.secondaryCpuAbi, 6799 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 6800 user, false); 6801 if (pkgSetting == null) { 6802 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6803 "Creating application package " + pkg.packageName + " failed"); 6804 } 6805 6806 if (pkgSetting.origPackage != null) { 6807 // If we are first transitioning from an original package, 6808 // fix up the new package's name now. We need to do this after 6809 // looking up the package under its new name, so getPackageLP 6810 // can take care of fiddling things correctly. 6811 pkg.setPackageName(origPackage.name); 6812 6813 // File a report about this. 6814 String msg = "New package " + pkgSetting.realName 6815 + " renamed to replace old package " + pkgSetting.name; 6816 reportSettingsProblem(Log.WARN, msg); 6817 6818 // Make a note of it. 6819 mTransferedPackages.add(origPackage.name); 6820 6821 // No longer need to retain this. 6822 pkgSetting.origPackage = null; 6823 } 6824 6825 if (realName != null) { 6826 // Make a note of it. 6827 mTransferedPackages.add(pkg.packageName); 6828 } 6829 6830 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 6831 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 6832 } 6833 6834 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6835 // Check all shared libraries and map to their actual file path. 6836 // We only do this here for apps not on a system dir, because those 6837 // are the only ones that can fail an install due to this. We 6838 // will take care of the system apps by updating all of their 6839 // library paths after the scan is done. 6840 updateSharedLibrariesLPw(pkg, null); 6841 } 6842 6843 if (mFoundPolicyFile) { 6844 SELinuxMMAC.assignSeinfoValue(pkg); 6845 } 6846 6847 pkg.applicationInfo.uid = pkgSetting.appId; 6848 pkg.mExtras = pkgSetting; 6849 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 6850 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 6851 // We just determined the app is signed correctly, so bring 6852 // over the latest parsed certs. 6853 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6854 } else { 6855 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6856 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6857 "Package " + pkg.packageName + " upgrade keys do not match the " 6858 + "previously installed version"); 6859 } else { 6860 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6861 String msg = "System package " + pkg.packageName 6862 + " signature changed; retaining data."; 6863 reportSettingsProblem(Log.WARN, msg); 6864 } 6865 } 6866 } else { 6867 try { 6868 verifySignaturesLP(pkgSetting, pkg); 6869 // We just determined the app is signed correctly, so bring 6870 // over the latest parsed certs. 6871 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6872 } catch (PackageManagerException e) { 6873 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6874 throw e; 6875 } 6876 // The signature has changed, but this package is in the system 6877 // image... let's recover! 6878 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6879 // However... if this package is part of a shared user, but it 6880 // doesn't match the signature of the shared user, let's fail. 6881 // What this means is that you can't change the signatures 6882 // associated with an overall shared user, which doesn't seem all 6883 // that unreasonable. 6884 if (pkgSetting.sharedUser != null) { 6885 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6886 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 6887 throw new PackageManagerException( 6888 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 6889 "Signature mismatch for shared user : " 6890 + pkgSetting.sharedUser); 6891 } 6892 } 6893 // File a report about this. 6894 String msg = "System package " + pkg.packageName 6895 + " signature changed; retaining data."; 6896 reportSettingsProblem(Log.WARN, msg); 6897 } 6898 } 6899 // Verify that this new package doesn't have any content providers 6900 // that conflict with existing packages. Only do this if the 6901 // package isn't already installed, since we don't want to break 6902 // things that are installed. 6903 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 6904 final int N = pkg.providers.size(); 6905 int i; 6906 for (i=0; i<N; i++) { 6907 PackageParser.Provider p = pkg.providers.get(i); 6908 if (p.info.authority != null) { 6909 String names[] = p.info.authority.split(";"); 6910 for (int j = 0; j < names.length; j++) { 6911 if (mProvidersByAuthority.containsKey(names[j])) { 6912 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6913 final String otherPackageName = 6914 ((other != null && other.getComponentName() != null) ? 6915 other.getComponentName().getPackageName() : "?"); 6916 throw new PackageManagerException( 6917 INSTALL_FAILED_CONFLICTING_PROVIDER, 6918 "Can't install because provider name " + names[j] 6919 + " (in package " + pkg.applicationInfo.packageName 6920 + ") is already used by " + otherPackageName); 6921 } 6922 } 6923 } 6924 } 6925 } 6926 6927 if (pkg.mAdoptPermissions != null) { 6928 // This package wants to adopt ownership of permissions from 6929 // another package. 6930 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 6931 final String origName = pkg.mAdoptPermissions.get(i); 6932 final PackageSetting orig = mSettings.peekPackageLPr(origName); 6933 if (orig != null) { 6934 if (verifyPackageUpdateLPr(orig, pkg)) { 6935 Slog.i(TAG, "Adopting permissions from " + origName + " to " 6936 + pkg.packageName); 6937 mSettings.transferPermissionsLPw(origName, pkg.packageName); 6938 } 6939 } 6940 } 6941 } 6942 } 6943 6944 final String pkgName = pkg.packageName; 6945 6946 final long scanFileTime = scanFile.lastModified(); 6947 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 6948 pkg.applicationInfo.processName = fixProcessName( 6949 pkg.applicationInfo.packageName, 6950 pkg.applicationInfo.processName, 6951 pkg.applicationInfo.uid); 6952 6953 File dataPath; 6954 if (mPlatformPackage == pkg) { 6955 // The system package is special. 6956 dataPath = new File(Environment.getDataDirectory(), "system"); 6957 6958 pkg.applicationInfo.dataDir = dataPath.getPath(); 6959 6960 } else { 6961 // This is a normal package, need to make its data directory. 6962 dataPath = Environment.getDataUserPackageDirectory(pkg.volumeUuid, 6963 UserHandle.USER_SYSTEM, pkg.packageName); 6964 6965 boolean uidError = false; 6966 if (dataPath.exists()) { 6967 int currentUid = 0; 6968 try { 6969 StructStat stat = Os.stat(dataPath.getPath()); 6970 currentUid = stat.st_uid; 6971 } catch (ErrnoException e) { 6972 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 6973 } 6974 6975 // If we have mismatched owners for the data path, we have a problem. 6976 if (currentUid != pkg.applicationInfo.uid) { 6977 boolean recovered = false; 6978 if (currentUid == 0) { 6979 // The directory somehow became owned by root. Wow. 6980 // This is probably because the system was stopped while 6981 // installd was in the middle of messing with its libs 6982 // directory. Ask installd to fix that. 6983 int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName, 6984 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 6985 if (ret >= 0) { 6986 recovered = true; 6987 String msg = "Package " + pkg.packageName 6988 + " unexpectedly changed to uid 0; recovered to " + 6989 + pkg.applicationInfo.uid; 6990 reportSettingsProblem(Log.WARN, msg); 6991 } 6992 } 6993 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6994 || (scanFlags&SCAN_BOOTING) != 0)) { 6995 // If this is a system app, we can at least delete its 6996 // current data so the application will still work. 6997 int ret = removeDataDirsLI(pkg.volumeUuid, pkgName); 6998 if (ret >= 0) { 6999 // TODO: Kill the processes first 7000 // Old data gone! 7001 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 7002 ? "System package " : "Third party package "; 7003 String msg = prefix + pkg.packageName 7004 + " has changed from uid: " 7005 + currentUid + " to " 7006 + pkg.applicationInfo.uid + "; old data erased"; 7007 reportSettingsProblem(Log.WARN, msg); 7008 recovered = true; 7009 7010 // And now re-install the app. 7011 ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 7012 pkg.applicationInfo.seinfo); 7013 if (ret == -1) { 7014 // Ack should not happen! 7015 msg = prefix + pkg.packageName 7016 + " could not have data directory re-created after delete."; 7017 reportSettingsProblem(Log.WARN, msg); 7018 throw new PackageManagerException( 7019 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 7020 } 7021 } 7022 if (!recovered) { 7023 mHasSystemUidErrors = true; 7024 } 7025 } else if (!recovered) { 7026 // If we allow this install to proceed, we will be broken. 7027 // Abort, abort! 7028 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 7029 "scanPackageLI"); 7030 } 7031 if (!recovered) { 7032 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 7033 + pkg.applicationInfo.uid + "/fs_" 7034 + currentUid; 7035 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 7036 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 7037 String msg = "Package " + pkg.packageName 7038 + " has mismatched uid: " 7039 + currentUid + " on disk, " 7040 + pkg.applicationInfo.uid + " in settings"; 7041 // writer 7042 synchronized (mPackages) { 7043 mSettings.mReadMessages.append(msg); 7044 mSettings.mReadMessages.append('\n'); 7045 uidError = true; 7046 if (!pkgSetting.uidError) { 7047 reportSettingsProblem(Log.ERROR, msg); 7048 } 7049 } 7050 } 7051 } 7052 pkg.applicationInfo.dataDir = dataPath.getPath(); 7053 if (mShouldRestoreconData) { 7054 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 7055 mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName, 7056 pkg.applicationInfo.seinfo, pkg.applicationInfo.uid); 7057 } 7058 } else { 7059 if (DEBUG_PACKAGE_SCANNING) { 7060 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7061 Log.v(TAG, "Want this data dir: " + dataPath); 7062 } 7063 //invoke installer to do the actual installation 7064 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 7065 pkg.applicationInfo.seinfo); 7066 if (ret < 0) { 7067 // Error from installer 7068 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7069 "Unable to create data dirs [errorCode=" + ret + "]"); 7070 } 7071 7072 if (dataPath.exists()) { 7073 pkg.applicationInfo.dataDir = dataPath.getPath(); 7074 } else { 7075 Slog.w(TAG, "Unable to create data directory: " + dataPath); 7076 pkg.applicationInfo.dataDir = null; 7077 } 7078 } 7079 7080 pkgSetting.uidError = uidError; 7081 } 7082 7083 final String path = scanFile.getPath(); 7084 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 7085 7086 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 7087 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 7088 7089 // Some system apps still use directory structure for native libraries 7090 // in which case we might end up not detecting abi solely based on apk 7091 // structure. Try to detect abi based on directory structure. 7092 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 7093 pkg.applicationInfo.primaryCpuAbi == null) { 7094 setBundledAppAbisAndRoots(pkg, pkgSetting); 7095 setNativeLibraryPaths(pkg); 7096 } 7097 7098 } else { 7099 if ((scanFlags & SCAN_MOVE) != 0) { 7100 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7101 // but we already have this packages package info in the PackageSetting. We just 7102 // use that and derive the native library path based on the new codepath. 7103 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7104 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7105 } 7106 7107 // Set native library paths again. For moves, the path will be updated based on the 7108 // ABIs we've determined above. For non-moves, the path will be updated based on the 7109 // ABIs we determined during compilation, but the path will depend on the final 7110 // package path (after the rename away from the stage path). 7111 setNativeLibraryPaths(pkg); 7112 } 7113 7114 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 7115 final int[] userIds = sUserManager.getUserIds(); 7116 synchronized (mInstallLock) { 7117 // Make sure all user data directories are ready to roll; we're okay 7118 // if they already exist 7119 if (!TextUtils.isEmpty(pkg.volumeUuid)) { 7120 for (int userId : userIds) { 7121 if (userId != UserHandle.USER_SYSTEM) { 7122 mInstaller.createUserData(pkg.volumeUuid, pkg.packageName, 7123 UserHandle.getUid(userId, pkg.applicationInfo.uid), userId, 7124 pkg.applicationInfo.seinfo); 7125 } 7126 } 7127 } 7128 7129 // Create a native library symlink only if we have native libraries 7130 // and if the native libraries are 32 bit libraries. We do not provide 7131 // this symlink for 64 bit libraries. 7132 if (pkg.applicationInfo.primaryCpuAbi != null && 7133 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 7134 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "linkNativeLib"); 7135 try { 7136 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 7137 for (int userId : userIds) { 7138 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 7139 nativeLibPath, userId) < 0) { 7140 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 7141 "Failed linking native library dir (user=" + userId + ")"); 7142 } 7143 } 7144 } finally { 7145 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7146 } 7147 } 7148 } 7149 7150 // This is a special case for the "system" package, where the ABI is 7151 // dictated by the zygote configuration (and init.rc). We should keep track 7152 // of this ABI so that we can deal with "normal" applications that run under 7153 // the same UID correctly. 7154 if (mPlatformPackage == pkg) { 7155 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7156 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7157 } 7158 7159 // If there's a mismatch between the abi-override in the package setting 7160 // and the abiOverride specified for the install. Warn about this because we 7161 // would've already compiled the app without taking the package setting into 7162 // account. 7163 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7164 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7165 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7166 " for package: " + pkg.packageName); 7167 } 7168 } 7169 7170 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7171 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7172 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7173 7174 // Copy the derived override back to the parsed package, so that we can 7175 // update the package settings accordingly. 7176 pkg.cpuAbiOverride = cpuAbiOverride; 7177 7178 if (DEBUG_ABI_SELECTION) { 7179 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7180 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7181 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7182 } 7183 7184 // Push the derived path down into PackageSettings so we know what to 7185 // clean up at uninstall time. 7186 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7187 7188 if (DEBUG_ABI_SELECTION) { 7189 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7190 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7191 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7192 } 7193 7194 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7195 // We don't do this here during boot because we can do it all 7196 // at once after scanning all existing packages. 7197 // 7198 // We also do this *before* we perform dexopt on this package, so that 7199 // we can avoid redundant dexopts, and also to make sure we've got the 7200 // code and package path correct. 7201 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7202 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, true /* boot complete */); 7203 } 7204 7205 if ((scanFlags & SCAN_NO_DEX) == 0) { 7206 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7207 7208 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, 7209 forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */, 7210 (scanFlags & SCAN_BOOTING) == 0, false /*useJit*/); 7211 7212 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7213 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7214 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 7215 } 7216 } 7217 if (mFactoryTest && pkg.requestedPermissions.contains( 7218 android.Manifest.permission.FACTORY_TEST)) { 7219 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7220 } 7221 7222 ArrayList<PackageParser.Package> clientLibPkgs = null; 7223 7224 // writer 7225 synchronized (mPackages) { 7226 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7227 // Only system apps can add new shared libraries. 7228 if (pkg.libraryNames != null) { 7229 for (int i=0; i<pkg.libraryNames.size(); i++) { 7230 String name = pkg.libraryNames.get(i); 7231 boolean allowed = false; 7232 if (pkg.isUpdatedSystemApp()) { 7233 // New library entries can only be added through the 7234 // system image. This is important to get rid of a lot 7235 // of nasty edge cases: for example if we allowed a non- 7236 // system update of the app to add a library, then uninstalling 7237 // the update would make the library go away, and assumptions 7238 // we made such as through app install filtering would now 7239 // have allowed apps on the device which aren't compatible 7240 // with it. Better to just have the restriction here, be 7241 // conservative, and create many fewer cases that can negatively 7242 // impact the user experience. 7243 final PackageSetting sysPs = mSettings 7244 .getDisabledSystemPkgLPr(pkg.packageName); 7245 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 7246 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 7247 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 7248 allowed = true; 7249 break; 7250 } 7251 } 7252 } 7253 } else { 7254 allowed = true; 7255 } 7256 if (allowed) { 7257 if (!mSharedLibraries.containsKey(name)) { 7258 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 7259 } else if (!name.equals(pkg.packageName)) { 7260 Slog.w(TAG, "Package " + pkg.packageName + " library " 7261 + name + " already exists; skipping"); 7262 } 7263 } else { 7264 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 7265 + name + " that is not declared on system image; skipping"); 7266 } 7267 } 7268 if ((scanFlags&SCAN_BOOTING) == 0) { 7269 // If we are not booting, we need to update any applications 7270 // that are clients of our shared library. If we are booting, 7271 // this will all be done once the scan is complete. 7272 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 7273 } 7274 } 7275 } 7276 } 7277 7278 // We also need to dexopt any apps that are dependent on this library. Note that 7279 // if these fail, we should abort the install since installing the library will 7280 // result in some apps being broken. 7281 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7282 try { 7283 if (clientLibPkgs != null) { 7284 if ((scanFlags & SCAN_NO_DEX) == 0) { 7285 for (int i = 0; i < clientLibPkgs.size(); i++) { 7286 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7287 int result = mPackageDexOptimizer.performDexOpt(clientPkg, 7288 null /* instruction sets */, forceDex, 7289 (scanFlags & SCAN_DEFER_DEX) != 0, false, 7290 (scanFlags & SCAN_BOOTING) == 0, false /*useJit*/); 7291 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7292 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 7293 "scanPackageLI failed to dexopt clientLibPkgs"); 7294 } 7295 } 7296 } 7297 } 7298 } finally { 7299 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7300 } 7301 7302 // Request the ActivityManager to kill the process(only for existing packages) 7303 // so that we do not end up in a confused state while the user is still using the older 7304 // version of the application while the new one gets installed. 7305 if ((scanFlags & SCAN_REPLACING) != 0) { 7306 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 7307 7308 killApplication(pkg.applicationInfo.packageName, 7309 pkg.applicationInfo.uid, "replace pkg"); 7310 7311 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7312 } 7313 7314 // Also need to kill any apps that are dependent on the library. 7315 if (clientLibPkgs != null) { 7316 for (int i=0; i<clientLibPkgs.size(); i++) { 7317 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7318 killApplication(clientPkg.applicationInfo.packageName, 7319 clientPkg.applicationInfo.uid, "update lib"); 7320 } 7321 } 7322 7323 // Make sure we're not adding any bogus keyset info 7324 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7325 ksms.assertScannedPackageValid(pkg); 7326 7327 // writer 7328 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 7329 7330 boolean createIdmapFailed = false; 7331 synchronized (mPackages) { 7332 // We don't expect installation to fail beyond this point 7333 7334 // Add the new setting to mSettings 7335 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 7336 // Add the new setting to mPackages 7337 mPackages.put(pkg.applicationInfo.packageName, pkg); 7338 // Make sure we don't accidentally delete its data. 7339 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 7340 while (iter.hasNext()) { 7341 PackageCleanItem item = iter.next(); 7342 if (pkgName.equals(item.packageName)) { 7343 iter.remove(); 7344 } 7345 } 7346 7347 // Take care of first install / last update times. 7348 if (currentTime != 0) { 7349 if (pkgSetting.firstInstallTime == 0) { 7350 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 7351 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 7352 pkgSetting.lastUpdateTime = currentTime; 7353 } 7354 } else if (pkgSetting.firstInstallTime == 0) { 7355 // We need *something*. Take time time stamp of the file. 7356 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 7357 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 7358 if (scanFileTime != pkgSetting.timeStamp) { 7359 // A package on the system image has changed; consider this 7360 // to be an update. 7361 pkgSetting.lastUpdateTime = scanFileTime; 7362 } 7363 } 7364 7365 // Add the package's KeySets to the global KeySetManagerService 7366 ksms.addScannedPackageLPw(pkg); 7367 7368 int N = pkg.providers.size(); 7369 StringBuilder r = null; 7370 int i; 7371 for (i=0; i<N; i++) { 7372 PackageParser.Provider p = pkg.providers.get(i); 7373 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 7374 p.info.processName, pkg.applicationInfo.uid); 7375 mProviders.addProvider(p); 7376 p.syncable = p.info.isSyncable; 7377 if (p.info.authority != null) { 7378 String names[] = p.info.authority.split(";"); 7379 p.info.authority = null; 7380 for (int j = 0; j < names.length; j++) { 7381 if (j == 1 && p.syncable) { 7382 // We only want the first authority for a provider to possibly be 7383 // syncable, so if we already added this provider using a different 7384 // authority clear the syncable flag. We copy the provider before 7385 // changing it because the mProviders object contains a reference 7386 // to a provider that we don't want to change. 7387 // Only do this for the second authority since the resulting provider 7388 // object can be the same for all future authorities for this provider. 7389 p = new PackageParser.Provider(p); 7390 p.syncable = false; 7391 } 7392 if (!mProvidersByAuthority.containsKey(names[j])) { 7393 mProvidersByAuthority.put(names[j], p); 7394 if (p.info.authority == null) { 7395 p.info.authority = names[j]; 7396 } else { 7397 p.info.authority = p.info.authority + ";" + names[j]; 7398 } 7399 if (DEBUG_PACKAGE_SCANNING) { 7400 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7401 Log.d(TAG, "Registered content provider: " + names[j] 7402 + ", className = " + p.info.name + ", isSyncable = " 7403 + p.info.isSyncable); 7404 } 7405 } else { 7406 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7407 Slog.w(TAG, "Skipping provider name " + names[j] + 7408 " (in package " + pkg.applicationInfo.packageName + 7409 "): name already used by " 7410 + ((other != null && other.getComponentName() != null) 7411 ? other.getComponentName().getPackageName() : "?")); 7412 } 7413 } 7414 } 7415 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7416 if (r == null) { 7417 r = new StringBuilder(256); 7418 } else { 7419 r.append(' '); 7420 } 7421 r.append(p.info.name); 7422 } 7423 } 7424 if (r != null) { 7425 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 7426 } 7427 7428 N = pkg.services.size(); 7429 r = null; 7430 for (i=0; i<N; i++) { 7431 PackageParser.Service s = pkg.services.get(i); 7432 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 7433 s.info.processName, pkg.applicationInfo.uid); 7434 mServices.addService(s); 7435 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7436 if (r == null) { 7437 r = new StringBuilder(256); 7438 } else { 7439 r.append(' '); 7440 } 7441 r.append(s.info.name); 7442 } 7443 } 7444 if (r != null) { 7445 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 7446 } 7447 7448 N = pkg.receivers.size(); 7449 r = null; 7450 for (i=0; i<N; i++) { 7451 PackageParser.Activity a = pkg.receivers.get(i); 7452 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 7453 a.info.processName, pkg.applicationInfo.uid); 7454 mReceivers.addActivity(a, "receiver"); 7455 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7456 if (r == null) { 7457 r = new StringBuilder(256); 7458 } else { 7459 r.append(' '); 7460 } 7461 r.append(a.info.name); 7462 } 7463 } 7464 if (r != null) { 7465 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 7466 } 7467 7468 N = pkg.activities.size(); 7469 r = null; 7470 for (i=0; i<N; i++) { 7471 PackageParser.Activity a = pkg.activities.get(i); 7472 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 7473 a.info.processName, pkg.applicationInfo.uid); 7474 mActivities.addActivity(a, "activity"); 7475 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7476 if (r == null) { 7477 r = new StringBuilder(256); 7478 } else { 7479 r.append(' '); 7480 } 7481 r.append(a.info.name); 7482 } 7483 } 7484 if (r != null) { 7485 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 7486 } 7487 7488 N = pkg.permissionGroups.size(); 7489 r = null; 7490 for (i=0; i<N; i++) { 7491 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 7492 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 7493 if (cur == null) { 7494 mPermissionGroups.put(pg.info.name, pg); 7495 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7496 if (r == null) { 7497 r = new StringBuilder(256); 7498 } else { 7499 r.append(' '); 7500 } 7501 r.append(pg.info.name); 7502 } 7503 } else { 7504 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 7505 + pg.info.packageName + " ignored: original from " 7506 + cur.info.packageName); 7507 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7508 if (r == null) { 7509 r = new StringBuilder(256); 7510 } else { 7511 r.append(' '); 7512 } 7513 r.append("DUP:"); 7514 r.append(pg.info.name); 7515 } 7516 } 7517 } 7518 if (r != null) { 7519 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 7520 } 7521 7522 N = pkg.permissions.size(); 7523 r = null; 7524 for (i=0; i<N; i++) { 7525 PackageParser.Permission p = pkg.permissions.get(i); 7526 7527 // Assume by default that we did not install this permission into the system. 7528 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 7529 7530 // Now that permission groups have a special meaning, we ignore permission 7531 // groups for legacy apps to prevent unexpected behavior. In particular, 7532 // permissions for one app being granted to someone just becuase they happen 7533 // to be in a group defined by another app (before this had no implications). 7534 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 7535 p.group = mPermissionGroups.get(p.info.group); 7536 // Warn for a permission in an unknown group. 7537 if (p.info.group != null && p.group == null) { 7538 Slog.w(TAG, "Permission " + p.info.name + " from package " 7539 + p.info.packageName + " in an unknown group " + p.info.group); 7540 } 7541 } 7542 7543 ArrayMap<String, BasePermission> permissionMap = 7544 p.tree ? mSettings.mPermissionTrees 7545 : mSettings.mPermissions; 7546 BasePermission bp = permissionMap.get(p.info.name); 7547 7548 // Allow system apps to redefine non-system permissions 7549 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 7550 final boolean currentOwnerIsSystem = (bp.perm != null 7551 && isSystemApp(bp.perm.owner)); 7552 if (isSystemApp(p.owner)) { 7553 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 7554 // It's a built-in permission and no owner, take ownership now 7555 bp.packageSetting = pkgSetting; 7556 bp.perm = p; 7557 bp.uid = pkg.applicationInfo.uid; 7558 bp.sourcePackage = p.info.packageName; 7559 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 7560 } else if (!currentOwnerIsSystem) { 7561 String msg = "New decl " + p.owner + " of permission " 7562 + p.info.name + " is system; overriding " + bp.sourcePackage; 7563 reportSettingsProblem(Log.WARN, msg); 7564 bp = null; 7565 } 7566 } 7567 } 7568 7569 if (bp == null) { 7570 bp = new BasePermission(p.info.name, p.info.packageName, 7571 BasePermission.TYPE_NORMAL); 7572 permissionMap.put(p.info.name, bp); 7573 } 7574 7575 if (bp.perm == null) { 7576 if (bp.sourcePackage == null 7577 || bp.sourcePackage.equals(p.info.packageName)) { 7578 BasePermission tree = findPermissionTreeLP(p.info.name); 7579 if (tree == null 7580 || tree.sourcePackage.equals(p.info.packageName)) { 7581 bp.packageSetting = pkgSetting; 7582 bp.perm = p; 7583 bp.uid = pkg.applicationInfo.uid; 7584 bp.sourcePackage = p.info.packageName; 7585 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 7586 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7587 if (r == null) { 7588 r = new StringBuilder(256); 7589 } else { 7590 r.append(' '); 7591 } 7592 r.append(p.info.name); 7593 } 7594 } else { 7595 Slog.w(TAG, "Permission " + p.info.name + " from package " 7596 + p.info.packageName + " ignored: base tree " 7597 + tree.name + " is from package " 7598 + tree.sourcePackage); 7599 } 7600 } else { 7601 Slog.w(TAG, "Permission " + p.info.name + " from package " 7602 + p.info.packageName + " ignored: original from " 7603 + bp.sourcePackage); 7604 } 7605 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7606 if (r == null) { 7607 r = new StringBuilder(256); 7608 } else { 7609 r.append(' '); 7610 } 7611 r.append("DUP:"); 7612 r.append(p.info.name); 7613 } 7614 if (bp.perm == p) { 7615 bp.protectionLevel = p.info.protectionLevel; 7616 } 7617 } 7618 7619 if (r != null) { 7620 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 7621 } 7622 7623 N = pkg.instrumentation.size(); 7624 r = null; 7625 for (i=0; i<N; i++) { 7626 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 7627 a.info.packageName = pkg.applicationInfo.packageName; 7628 a.info.sourceDir = pkg.applicationInfo.sourceDir; 7629 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 7630 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 7631 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 7632 a.info.dataDir = pkg.applicationInfo.dataDir; 7633 7634 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 7635 // need other information about the application, like the ABI and what not ? 7636 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 7637 mInstrumentation.put(a.getComponentName(), a); 7638 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7639 if (r == null) { 7640 r = new StringBuilder(256); 7641 } else { 7642 r.append(' '); 7643 } 7644 r.append(a.info.name); 7645 } 7646 } 7647 if (r != null) { 7648 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 7649 } 7650 7651 if (pkg.protectedBroadcasts != null) { 7652 N = pkg.protectedBroadcasts.size(); 7653 for (i=0; i<N; i++) { 7654 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 7655 } 7656 } 7657 7658 pkgSetting.setTimeStamp(scanFileTime); 7659 7660 // Create idmap files for pairs of (packages, overlay packages). 7661 // Note: "android", ie framework-res.apk, is handled by native layers. 7662 if (pkg.mOverlayTarget != null) { 7663 // This is an overlay package. 7664 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 7665 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 7666 mOverlays.put(pkg.mOverlayTarget, 7667 new ArrayMap<String, PackageParser.Package>()); 7668 } 7669 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 7670 map.put(pkg.packageName, pkg); 7671 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 7672 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 7673 createIdmapFailed = true; 7674 } 7675 } 7676 } else if (mOverlays.containsKey(pkg.packageName) && 7677 !pkg.packageName.equals("android")) { 7678 // This is a regular package, with one or more known overlay packages. 7679 createIdmapsForPackageLI(pkg); 7680 } 7681 } 7682 7683 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7684 7685 if (createIdmapFailed) { 7686 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7687 "scanPackageLI failed to createIdmap"); 7688 } 7689 return pkg; 7690 } 7691 7692 /** 7693 * Derive the ABI of a non-system package located at {@code scanFile}. This information 7694 * is derived purely on the basis of the contents of {@code scanFile} and 7695 * {@code cpuAbiOverride}. 7696 * 7697 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 7698 */ 7699 public void derivePackageAbi(PackageParser.Package pkg, File scanFile, 7700 String cpuAbiOverride, boolean extractLibs) 7701 throws PackageManagerException { 7702 // TODO: We can probably be smarter about this stuff. For installed apps, 7703 // we can calculate this information at install time once and for all. For 7704 // system apps, we can probably assume that this information doesn't change 7705 // after the first boot scan. As things stand, we do lots of unnecessary work. 7706 7707 // Give ourselves some initial paths; we'll come back for another 7708 // pass once we've determined ABI below. 7709 setNativeLibraryPaths(pkg); 7710 7711 // We would never need to extract libs for forward-locked and external packages, 7712 // since the container service will do it for us. We shouldn't attempt to 7713 // extract libs from system app when it was not updated. 7714 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 7715 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 7716 extractLibs = false; 7717 } 7718 7719 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 7720 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 7721 7722 NativeLibraryHelper.Handle handle = null; 7723 try { 7724 handle = NativeLibraryHelper.Handle.create(pkg); 7725 // TODO(multiArch): This can be null for apps that didn't go through the 7726 // usual installation process. We can calculate it again, like we 7727 // do during install time. 7728 // 7729 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 7730 // unnecessary. 7731 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 7732 7733 // Null out the abis so that they can be recalculated. 7734 pkg.applicationInfo.primaryCpuAbi = null; 7735 pkg.applicationInfo.secondaryCpuAbi = null; 7736 if (isMultiArch(pkg.applicationInfo)) { 7737 // Warn if we've set an abiOverride for multi-lib packages.. 7738 // By definition, we need to copy both 32 and 64 bit libraries for 7739 // such packages. 7740 if (pkg.cpuAbiOverride != null 7741 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 7742 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 7743 } 7744 7745 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 7746 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 7747 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 7748 if (extractLibs) { 7749 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7750 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 7751 useIsaSpecificSubdirs); 7752 } else { 7753 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 7754 } 7755 } 7756 7757 maybeThrowExceptionForMultiArchCopy( 7758 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 7759 7760 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 7761 if (extractLibs) { 7762 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7763 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 7764 useIsaSpecificSubdirs); 7765 } else { 7766 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 7767 } 7768 } 7769 7770 maybeThrowExceptionForMultiArchCopy( 7771 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 7772 7773 if (abi64 >= 0) { 7774 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 7775 } 7776 7777 if (abi32 >= 0) { 7778 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 7779 if (abi64 >= 0) { 7780 pkg.applicationInfo.secondaryCpuAbi = abi; 7781 } else { 7782 pkg.applicationInfo.primaryCpuAbi = abi; 7783 } 7784 } 7785 } else { 7786 String[] abiList = (cpuAbiOverride != null) ? 7787 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 7788 7789 // Enable gross and lame hacks for apps that are built with old 7790 // SDK tools. We must scan their APKs for renderscript bitcode and 7791 // not launch them if it's present. Don't bother checking on devices 7792 // that don't have 64 bit support. 7793 boolean needsRenderScriptOverride = false; 7794 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 7795 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 7796 abiList = Build.SUPPORTED_32_BIT_ABIS; 7797 needsRenderScriptOverride = true; 7798 } 7799 7800 final int copyRet; 7801 if (extractLibs) { 7802 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7803 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 7804 } else { 7805 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 7806 } 7807 7808 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 7809 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 7810 "Error unpackaging native libs for app, errorCode=" + copyRet); 7811 } 7812 7813 if (copyRet >= 0) { 7814 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 7815 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 7816 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 7817 } else if (needsRenderScriptOverride) { 7818 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 7819 } 7820 } 7821 } catch (IOException ioe) { 7822 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 7823 } finally { 7824 IoUtils.closeQuietly(handle); 7825 } 7826 7827 // Now that we've calculated the ABIs and determined if it's an internal app, 7828 // we will go ahead and populate the nativeLibraryPath. 7829 setNativeLibraryPaths(pkg); 7830 } 7831 7832 /** 7833 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 7834 * i.e, so that all packages can be run inside a single process if required. 7835 * 7836 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 7837 * this function will either try and make the ABI for all packages in {@code packagesForUser} 7838 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 7839 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 7840 * updating a package that belongs to a shared user. 7841 * 7842 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 7843 * adds unnecessary complexity. 7844 */ 7845 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 7846 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt, 7847 boolean bootComplete) { 7848 String requiredInstructionSet = null; 7849 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 7850 requiredInstructionSet = VMRuntime.getInstructionSet( 7851 scannedPackage.applicationInfo.primaryCpuAbi); 7852 } 7853 7854 PackageSetting requirer = null; 7855 for (PackageSetting ps : packagesForUser) { 7856 // If packagesForUser contains scannedPackage, we skip it. This will happen 7857 // when scannedPackage is an update of an existing package. Without this check, 7858 // we will never be able to change the ABI of any package belonging to a shared 7859 // user, even if it's compatible with other packages. 7860 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7861 if (ps.primaryCpuAbiString == null) { 7862 continue; 7863 } 7864 7865 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 7866 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 7867 // We have a mismatch between instruction sets (say arm vs arm64) warn about 7868 // this but there's not much we can do. 7869 String errorMessage = "Instruction set mismatch, " 7870 + ((requirer == null) ? "[caller]" : requirer) 7871 + " requires " + requiredInstructionSet + " whereas " + ps 7872 + " requires " + instructionSet; 7873 Slog.w(TAG, errorMessage); 7874 } 7875 7876 if (requiredInstructionSet == null) { 7877 requiredInstructionSet = instructionSet; 7878 requirer = ps; 7879 } 7880 } 7881 } 7882 7883 if (requiredInstructionSet != null) { 7884 String adjustedAbi; 7885 if (requirer != null) { 7886 // requirer != null implies that either scannedPackage was null or that scannedPackage 7887 // did not require an ABI, in which case we have to adjust scannedPackage to match 7888 // the ABI of the set (which is the same as requirer's ABI) 7889 adjustedAbi = requirer.primaryCpuAbiString; 7890 if (scannedPackage != null) { 7891 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 7892 } 7893 } else { 7894 // requirer == null implies that we're updating all ABIs in the set to 7895 // match scannedPackage. 7896 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 7897 } 7898 7899 for (PackageSetting ps : packagesForUser) { 7900 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7901 if (ps.primaryCpuAbiString != null) { 7902 continue; 7903 } 7904 7905 ps.primaryCpuAbiString = adjustedAbi; 7906 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 7907 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 7908 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 7909 7910 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7911 7912 int result = mPackageDexOptimizer.performDexOpt(ps.pkg, 7913 null /* instruction sets */, forceDexOpt, deferDexOpt, true, 7914 bootComplete, false /*useJit*/); 7915 7916 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7917 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7918 ps.primaryCpuAbiString = null; 7919 ps.pkg.applicationInfo.primaryCpuAbi = null; 7920 return; 7921 } else { 7922 mInstaller.rmdex(ps.codePathString, 7923 getDexCodeInstructionSet(getPreferredInstructionSet())); 7924 } 7925 } 7926 } 7927 } 7928 } 7929 } 7930 7931 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 7932 synchronized (mPackages) { 7933 mResolverReplaced = true; 7934 // Set up information for custom user intent resolution activity. 7935 mResolveActivity.applicationInfo = pkg.applicationInfo; 7936 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 7937 mResolveActivity.packageName = pkg.applicationInfo.packageName; 7938 mResolveActivity.processName = pkg.applicationInfo.packageName; 7939 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7940 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 7941 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 7942 mResolveActivity.theme = 0; 7943 mResolveActivity.exported = true; 7944 mResolveActivity.enabled = true; 7945 mResolveInfo.activityInfo = mResolveActivity; 7946 mResolveInfo.priority = 0; 7947 mResolveInfo.preferredOrder = 0; 7948 mResolveInfo.match = 0; 7949 mResolveComponentName = mCustomResolverComponentName; 7950 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 7951 mResolveComponentName); 7952 } 7953 } 7954 7955 private static String calculateBundledApkRoot(final String codePathString) { 7956 final File codePath = new File(codePathString); 7957 final File codeRoot; 7958 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 7959 codeRoot = Environment.getRootDirectory(); 7960 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 7961 codeRoot = Environment.getOemDirectory(); 7962 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 7963 codeRoot = Environment.getVendorDirectory(); 7964 } else { 7965 // Unrecognized code path; take its top real segment as the apk root: 7966 // e.g. /something/app/blah.apk => /something 7967 try { 7968 File f = codePath.getCanonicalFile(); 7969 File parent = f.getParentFile(); // non-null because codePath is a file 7970 File tmp; 7971 while ((tmp = parent.getParentFile()) != null) { 7972 f = parent; 7973 parent = tmp; 7974 } 7975 codeRoot = f; 7976 Slog.w(TAG, "Unrecognized code path " 7977 + codePath + " - using " + codeRoot); 7978 } catch (IOException e) { 7979 // Can't canonicalize the code path -- shenanigans? 7980 Slog.w(TAG, "Can't canonicalize code path " + codePath); 7981 return Environment.getRootDirectory().getPath(); 7982 } 7983 } 7984 return codeRoot.getPath(); 7985 } 7986 7987 /** 7988 * Derive and set the location of native libraries for the given package, 7989 * which varies depending on where and how the package was installed. 7990 */ 7991 private void setNativeLibraryPaths(PackageParser.Package pkg) { 7992 final ApplicationInfo info = pkg.applicationInfo; 7993 final String codePath = pkg.codePath; 7994 final File codeFile = new File(codePath); 7995 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 7996 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 7997 7998 info.nativeLibraryRootDir = null; 7999 info.nativeLibraryRootRequiresIsa = false; 8000 info.nativeLibraryDir = null; 8001 info.secondaryNativeLibraryDir = null; 8002 8003 if (isApkFile(codeFile)) { 8004 // Monolithic install 8005 if (bundledApp) { 8006 // If "/system/lib64/apkname" exists, assume that is the per-package 8007 // native library directory to use; otherwise use "/system/lib/apkname". 8008 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 8009 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 8010 getPrimaryInstructionSet(info)); 8011 8012 // This is a bundled system app so choose the path based on the ABI. 8013 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 8014 // is just the default path. 8015 final String apkName = deriveCodePathName(codePath); 8016 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 8017 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 8018 apkName).getAbsolutePath(); 8019 8020 if (info.secondaryCpuAbi != null) { 8021 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 8022 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 8023 secondaryLibDir, apkName).getAbsolutePath(); 8024 } 8025 } else if (asecApp) { 8026 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 8027 .getAbsolutePath(); 8028 } else { 8029 final String apkName = deriveCodePathName(codePath); 8030 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 8031 .getAbsolutePath(); 8032 } 8033 8034 info.nativeLibraryRootRequiresIsa = false; 8035 info.nativeLibraryDir = info.nativeLibraryRootDir; 8036 } else { 8037 // Cluster install 8038 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 8039 info.nativeLibraryRootRequiresIsa = true; 8040 8041 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 8042 getPrimaryInstructionSet(info)).getAbsolutePath(); 8043 8044 if (info.secondaryCpuAbi != null) { 8045 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 8046 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 8047 } 8048 } 8049 } 8050 8051 /** 8052 * Calculate the abis and roots for a bundled app. These can uniquely 8053 * be determined from the contents of the system partition, i.e whether 8054 * it contains 64 or 32 bit shared libraries etc. We do not validate any 8055 * of this information, and instead assume that the system was built 8056 * sensibly. 8057 */ 8058 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 8059 PackageSetting pkgSetting) { 8060 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 8061 8062 // If "/system/lib64/apkname" exists, assume that is the per-package 8063 // native library directory to use; otherwise use "/system/lib/apkname". 8064 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 8065 setBundledAppAbi(pkg, apkRoot, apkName); 8066 // pkgSetting might be null during rescan following uninstall of updates 8067 // to a bundled app, so accommodate that possibility. The settings in 8068 // that case will be established later from the parsed package. 8069 // 8070 // If the settings aren't null, sync them up with what we've just derived. 8071 // note that apkRoot isn't stored in the package settings. 8072 if (pkgSetting != null) { 8073 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8074 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8075 } 8076 } 8077 8078 /** 8079 * Deduces the ABI of a bundled app and sets the relevant fields on the 8080 * parsed pkg object. 8081 * 8082 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 8083 * under which system libraries are installed. 8084 * @param apkName the name of the installed package. 8085 */ 8086 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 8087 final File codeFile = new File(pkg.codePath); 8088 8089 final boolean has64BitLibs; 8090 final boolean has32BitLibs; 8091 if (isApkFile(codeFile)) { 8092 // Monolithic install 8093 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 8094 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 8095 } else { 8096 // Cluster install 8097 final File rootDir = new File(codeFile, LIB_DIR_NAME); 8098 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 8099 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 8100 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 8101 has64BitLibs = (new File(rootDir, isa)).exists(); 8102 } else { 8103 has64BitLibs = false; 8104 } 8105 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 8106 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 8107 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 8108 has32BitLibs = (new File(rootDir, isa)).exists(); 8109 } else { 8110 has32BitLibs = false; 8111 } 8112 } 8113 8114 if (has64BitLibs && !has32BitLibs) { 8115 // The package has 64 bit libs, but not 32 bit libs. Its primary 8116 // ABI should be 64 bit. We can safely assume here that the bundled 8117 // native libraries correspond to the most preferred ABI in the list. 8118 8119 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8120 pkg.applicationInfo.secondaryCpuAbi = null; 8121 } else if (has32BitLibs && !has64BitLibs) { 8122 // The package has 32 bit libs but not 64 bit libs. Its primary 8123 // ABI should be 32 bit. 8124 8125 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8126 pkg.applicationInfo.secondaryCpuAbi = null; 8127 } else if (has32BitLibs && has64BitLibs) { 8128 // The application has both 64 and 32 bit bundled libraries. We check 8129 // here that the app declares multiArch support, and warn if it doesn't. 8130 // 8131 // We will be lenient here and record both ABIs. The primary will be the 8132 // ABI that's higher on the list, i.e, a device that's configured to prefer 8133 // 64 bit apps will see a 64 bit primary ABI, 8134 8135 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8136 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 8137 } 8138 8139 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8140 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8141 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8142 } else { 8143 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8144 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8145 } 8146 } else { 8147 pkg.applicationInfo.primaryCpuAbi = null; 8148 pkg.applicationInfo.secondaryCpuAbi = null; 8149 } 8150 } 8151 8152 private void killApplication(String pkgName, int appId, String reason) { 8153 // Request the ActivityManager to kill the process(only for existing packages) 8154 // so that we do not end up in a confused state while the user is still using the older 8155 // version of the application while the new one gets installed. 8156 IActivityManager am = ActivityManagerNative.getDefault(); 8157 if (am != null) { 8158 try { 8159 am.killApplicationWithAppId(pkgName, appId, reason); 8160 } catch (RemoteException e) { 8161 } 8162 } 8163 } 8164 8165 void removePackageLI(PackageSetting ps, boolean chatty) { 8166 if (DEBUG_INSTALL) { 8167 if (chatty) 8168 Log.d(TAG, "Removing package " + ps.name); 8169 } 8170 8171 // writer 8172 synchronized (mPackages) { 8173 mPackages.remove(ps.name); 8174 final PackageParser.Package pkg = ps.pkg; 8175 if (pkg != null) { 8176 cleanPackageDataStructuresLILPw(pkg, chatty); 8177 } 8178 } 8179 } 8180 8181 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8182 if (DEBUG_INSTALL) { 8183 if (chatty) 8184 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8185 } 8186 8187 // writer 8188 synchronized (mPackages) { 8189 mPackages.remove(pkg.applicationInfo.packageName); 8190 cleanPackageDataStructuresLILPw(pkg, chatty); 8191 } 8192 } 8193 8194 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8195 int N = pkg.providers.size(); 8196 StringBuilder r = null; 8197 int i; 8198 for (i=0; i<N; i++) { 8199 PackageParser.Provider p = pkg.providers.get(i); 8200 mProviders.removeProvider(p); 8201 if (p.info.authority == null) { 8202 8203 /* There was another ContentProvider with this authority when 8204 * this app was installed so this authority is null, 8205 * Ignore it as we don't have to unregister the provider. 8206 */ 8207 continue; 8208 } 8209 String names[] = p.info.authority.split(";"); 8210 for (int j = 0; j < names.length; j++) { 8211 if (mProvidersByAuthority.get(names[j]) == p) { 8212 mProvidersByAuthority.remove(names[j]); 8213 if (DEBUG_REMOVE) { 8214 if (chatty) 8215 Log.d(TAG, "Unregistered content provider: " + names[j] 8216 + ", className = " + p.info.name + ", isSyncable = " 8217 + p.info.isSyncable); 8218 } 8219 } 8220 } 8221 if (DEBUG_REMOVE && chatty) { 8222 if (r == null) { 8223 r = new StringBuilder(256); 8224 } else { 8225 r.append(' '); 8226 } 8227 r.append(p.info.name); 8228 } 8229 } 8230 if (r != null) { 8231 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 8232 } 8233 8234 N = pkg.services.size(); 8235 r = null; 8236 for (i=0; i<N; i++) { 8237 PackageParser.Service s = pkg.services.get(i); 8238 mServices.removeService(s); 8239 if (chatty) { 8240 if (r == null) { 8241 r = new StringBuilder(256); 8242 } else { 8243 r.append(' '); 8244 } 8245 r.append(s.info.name); 8246 } 8247 } 8248 if (r != null) { 8249 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 8250 } 8251 8252 N = pkg.receivers.size(); 8253 r = null; 8254 for (i=0; i<N; i++) { 8255 PackageParser.Activity a = pkg.receivers.get(i); 8256 mReceivers.removeActivity(a, "receiver"); 8257 if (DEBUG_REMOVE && chatty) { 8258 if (r == null) { 8259 r = new StringBuilder(256); 8260 } else { 8261 r.append(' '); 8262 } 8263 r.append(a.info.name); 8264 } 8265 } 8266 if (r != null) { 8267 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 8268 } 8269 8270 N = pkg.activities.size(); 8271 r = null; 8272 for (i=0; i<N; i++) { 8273 PackageParser.Activity a = pkg.activities.get(i); 8274 mActivities.removeActivity(a, "activity"); 8275 if (DEBUG_REMOVE && chatty) { 8276 if (r == null) { 8277 r = new StringBuilder(256); 8278 } else { 8279 r.append(' '); 8280 } 8281 r.append(a.info.name); 8282 } 8283 } 8284 if (r != null) { 8285 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 8286 } 8287 8288 N = pkg.permissions.size(); 8289 r = null; 8290 for (i=0; i<N; i++) { 8291 PackageParser.Permission p = pkg.permissions.get(i); 8292 BasePermission bp = mSettings.mPermissions.get(p.info.name); 8293 if (bp == null) { 8294 bp = mSettings.mPermissionTrees.get(p.info.name); 8295 } 8296 if (bp != null && bp.perm == p) { 8297 bp.perm = null; 8298 if (DEBUG_REMOVE && chatty) { 8299 if (r == null) { 8300 r = new StringBuilder(256); 8301 } else { 8302 r.append(' '); 8303 } 8304 r.append(p.info.name); 8305 } 8306 } 8307 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8308 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 8309 if (appOpPerms != null) { 8310 appOpPerms.remove(pkg.packageName); 8311 } 8312 } 8313 } 8314 if (r != null) { 8315 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8316 } 8317 8318 N = pkg.requestedPermissions.size(); 8319 r = null; 8320 for (i=0; i<N; i++) { 8321 String perm = pkg.requestedPermissions.get(i); 8322 BasePermission bp = mSettings.mPermissions.get(perm); 8323 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8324 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 8325 if (appOpPerms != null) { 8326 appOpPerms.remove(pkg.packageName); 8327 if (appOpPerms.isEmpty()) { 8328 mAppOpPermissionPackages.remove(perm); 8329 } 8330 } 8331 } 8332 } 8333 if (r != null) { 8334 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8335 } 8336 8337 N = pkg.instrumentation.size(); 8338 r = null; 8339 for (i=0; i<N; i++) { 8340 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8341 mInstrumentation.remove(a.getComponentName()); 8342 if (DEBUG_REMOVE && chatty) { 8343 if (r == null) { 8344 r = new StringBuilder(256); 8345 } else { 8346 r.append(' '); 8347 } 8348 r.append(a.info.name); 8349 } 8350 } 8351 if (r != null) { 8352 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 8353 } 8354 8355 r = null; 8356 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8357 // Only system apps can hold shared libraries. 8358 if (pkg.libraryNames != null) { 8359 for (i=0; i<pkg.libraryNames.size(); i++) { 8360 String name = pkg.libraryNames.get(i); 8361 SharedLibraryEntry cur = mSharedLibraries.get(name); 8362 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 8363 mSharedLibraries.remove(name); 8364 if (DEBUG_REMOVE && chatty) { 8365 if (r == null) { 8366 r = new StringBuilder(256); 8367 } else { 8368 r.append(' '); 8369 } 8370 r.append(name); 8371 } 8372 } 8373 } 8374 } 8375 } 8376 if (r != null) { 8377 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 8378 } 8379 } 8380 8381 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 8382 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 8383 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 8384 return true; 8385 } 8386 } 8387 return false; 8388 } 8389 8390 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 8391 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 8392 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 8393 8394 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 8395 int flags) { 8396 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 8397 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 8398 } 8399 8400 private void updatePermissionsLPw(String changingPkg, 8401 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 8402 // Make sure there are no dangling permission trees. 8403 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 8404 while (it.hasNext()) { 8405 final BasePermission bp = it.next(); 8406 if (bp.packageSetting == null) { 8407 // We may not yet have parsed the package, so just see if 8408 // we still know about its settings. 8409 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 8410 } 8411 if (bp.packageSetting == null) { 8412 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 8413 + " from package " + bp.sourcePackage); 8414 it.remove(); 8415 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 8416 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 8417 Slog.i(TAG, "Removing old permission tree: " + bp.name 8418 + " from package " + bp.sourcePackage); 8419 flags |= UPDATE_PERMISSIONS_ALL; 8420 it.remove(); 8421 } 8422 } 8423 } 8424 8425 // Make sure all dynamic permissions have been assigned to a package, 8426 // and make sure there are no dangling permissions. 8427 it = mSettings.mPermissions.values().iterator(); 8428 while (it.hasNext()) { 8429 final BasePermission bp = it.next(); 8430 if (bp.type == BasePermission.TYPE_DYNAMIC) { 8431 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 8432 + bp.name + " pkg=" + bp.sourcePackage 8433 + " info=" + bp.pendingInfo); 8434 if (bp.packageSetting == null && bp.pendingInfo != null) { 8435 final BasePermission tree = findPermissionTreeLP(bp.name); 8436 if (tree != null && tree.perm != null) { 8437 bp.packageSetting = tree.packageSetting; 8438 bp.perm = new PackageParser.Permission(tree.perm.owner, 8439 new PermissionInfo(bp.pendingInfo)); 8440 bp.perm.info.packageName = tree.perm.info.packageName; 8441 bp.perm.info.name = bp.name; 8442 bp.uid = tree.uid; 8443 } 8444 } 8445 } 8446 if (bp.packageSetting == null) { 8447 // We may not yet have parsed the package, so just see if 8448 // we still know about its settings. 8449 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 8450 } 8451 if (bp.packageSetting == null) { 8452 Slog.w(TAG, "Removing dangling permission: " + bp.name 8453 + " from package " + bp.sourcePackage); 8454 it.remove(); 8455 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 8456 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 8457 Slog.i(TAG, "Removing old permission: " + bp.name 8458 + " from package " + bp.sourcePackage); 8459 flags |= UPDATE_PERMISSIONS_ALL; 8460 it.remove(); 8461 } 8462 } 8463 } 8464 8465 // Now update the permissions for all packages, in particular 8466 // replace the granted permissions of the system packages. 8467 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 8468 for (PackageParser.Package pkg : mPackages.values()) { 8469 if (pkg != pkgInfo) { 8470 // Only replace for packages on requested volume 8471 final String volumeUuid = getVolumeUuidForPackage(pkg); 8472 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 8473 && Objects.equals(replaceVolumeUuid, volumeUuid); 8474 grantPermissionsLPw(pkg, replace, changingPkg); 8475 } 8476 } 8477 } 8478 8479 if (pkgInfo != null) { 8480 // Only replace for packages on requested volume 8481 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 8482 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 8483 && Objects.equals(replaceVolumeUuid, volumeUuid); 8484 grantPermissionsLPw(pkgInfo, replace, changingPkg); 8485 } 8486 } 8487 8488 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 8489 String packageOfInterest) { 8490 // IMPORTANT: There are two types of permissions: install and runtime. 8491 // Install time permissions are granted when the app is installed to 8492 // all device users and users added in the future. Runtime permissions 8493 // are granted at runtime explicitly to specific users. Normal and signature 8494 // protected permissions are install time permissions. Dangerous permissions 8495 // are install permissions if the app's target SDK is Lollipop MR1 or older, 8496 // otherwise they are runtime permissions. This function does not manage 8497 // runtime permissions except for the case an app targeting Lollipop MR1 8498 // being upgraded to target a newer SDK, in which case dangerous permissions 8499 // are transformed from install time to runtime ones. 8500 8501 final PackageSetting ps = (PackageSetting) pkg.mExtras; 8502 if (ps == null) { 8503 return; 8504 } 8505 8506 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 8507 8508 PermissionsState permissionsState = ps.getPermissionsState(); 8509 PermissionsState origPermissions = permissionsState; 8510 8511 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 8512 8513 boolean runtimePermissionsRevoked = false; 8514 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 8515 8516 boolean changedInstallPermission = false; 8517 8518 if (replace) { 8519 ps.installPermissionsFixed = false; 8520 if (!ps.isSharedUser()) { 8521 origPermissions = new PermissionsState(permissionsState); 8522 permissionsState.reset(); 8523 } else { 8524 // We need to know only about runtime permission changes since the 8525 // calling code always writes the install permissions state but 8526 // the runtime ones are written only if changed. The only cases of 8527 // changed runtime permissions here are promotion of an install to 8528 // runtime and revocation of a runtime from a shared user. 8529 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 8530 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 8531 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 8532 runtimePermissionsRevoked = true; 8533 } 8534 } 8535 } 8536 8537 permissionsState.setGlobalGids(mGlobalGids); 8538 8539 final int N = pkg.requestedPermissions.size(); 8540 for (int i=0; i<N; i++) { 8541 final String name = pkg.requestedPermissions.get(i); 8542 final BasePermission bp = mSettings.mPermissions.get(name); 8543 8544 if (DEBUG_INSTALL) { 8545 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 8546 } 8547 8548 if (bp == null || bp.packageSetting == null) { 8549 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 8550 Slog.w(TAG, "Unknown permission " + name 8551 + " in package " + pkg.packageName); 8552 } 8553 continue; 8554 } 8555 8556 final String perm = bp.name; 8557 boolean allowedSig = false; 8558 int grant = GRANT_DENIED; 8559 8560 // Keep track of app op permissions. 8561 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8562 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 8563 if (pkgs == null) { 8564 pkgs = new ArraySet<>(); 8565 mAppOpPermissionPackages.put(bp.name, pkgs); 8566 } 8567 pkgs.add(pkg.packageName); 8568 } 8569 8570 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 8571 switch (level) { 8572 case PermissionInfo.PROTECTION_NORMAL: { 8573 // For all apps normal permissions are install time ones. 8574 grant = GRANT_INSTALL; 8575 } break; 8576 8577 case PermissionInfo.PROTECTION_DANGEROUS: { 8578 if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) { 8579 // For legacy apps dangerous permissions are install time ones. 8580 grant = GRANT_INSTALL_LEGACY; 8581 } else if (origPermissions.hasInstallPermission(bp.name)) { 8582 // For legacy apps that became modern, install becomes runtime. 8583 grant = GRANT_UPGRADE; 8584 } else if (mPromoteSystemApps 8585 && isSystemApp(ps) 8586 && mExistingSystemPackages.contains(ps.name)) { 8587 // For legacy system apps, install becomes runtime. 8588 // We cannot check hasInstallPermission() for system apps since those 8589 // permissions were granted implicitly and not persisted pre-M. 8590 grant = GRANT_UPGRADE; 8591 } else { 8592 // For modern apps keep runtime permissions unchanged. 8593 grant = GRANT_RUNTIME; 8594 } 8595 } break; 8596 8597 case PermissionInfo.PROTECTION_SIGNATURE: { 8598 // For all apps signature permissions are install time ones. 8599 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 8600 if (allowedSig) { 8601 grant = GRANT_INSTALL; 8602 } 8603 } break; 8604 } 8605 8606 if (DEBUG_INSTALL) { 8607 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 8608 } 8609 8610 if (grant != GRANT_DENIED) { 8611 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 8612 // If this is an existing, non-system package, then 8613 // we can't add any new permissions to it. 8614 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 8615 // Except... if this is a permission that was added 8616 // to the platform (note: need to only do this when 8617 // updating the platform). 8618 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 8619 grant = GRANT_DENIED; 8620 } 8621 } 8622 } 8623 8624 switch (grant) { 8625 case GRANT_INSTALL: { 8626 // Revoke this as runtime permission to handle the case of 8627 // a runtime permission being downgraded to an install one. 8628 for (int userId : UserManagerService.getInstance().getUserIds()) { 8629 if (origPermissions.getRuntimePermissionState( 8630 bp.name, userId) != null) { 8631 // Revoke the runtime permission and clear the flags. 8632 origPermissions.revokeRuntimePermission(bp, userId); 8633 origPermissions.updatePermissionFlags(bp, userId, 8634 PackageManager.MASK_PERMISSION_FLAGS, 0); 8635 // If we revoked a permission permission, we have to write. 8636 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8637 changedRuntimePermissionUserIds, userId); 8638 } 8639 } 8640 // Grant an install permission. 8641 if (permissionsState.grantInstallPermission(bp) != 8642 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8643 changedInstallPermission = true; 8644 } 8645 } break; 8646 8647 case GRANT_INSTALL_LEGACY: { 8648 // Grant an install permission. 8649 if (permissionsState.grantInstallPermission(bp) != 8650 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8651 changedInstallPermission = true; 8652 } 8653 } break; 8654 8655 case GRANT_RUNTIME: { 8656 // Grant previously granted runtime permissions. 8657 for (int userId : UserManagerService.getInstance().getUserIds()) { 8658 PermissionState permissionState = origPermissions 8659 .getRuntimePermissionState(bp.name, userId); 8660 final int flags = permissionState != null 8661 ? permissionState.getFlags() : 0; 8662 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 8663 if (permissionsState.grantRuntimePermission(bp, userId) == 8664 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8665 // If we cannot put the permission as it was, we have to write. 8666 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8667 changedRuntimePermissionUserIds, userId); 8668 } 8669 } 8670 // Propagate the permission flags. 8671 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 8672 } 8673 } break; 8674 8675 case GRANT_UPGRADE: { 8676 // Grant runtime permissions for a previously held install permission. 8677 PermissionState permissionState = origPermissions 8678 .getInstallPermissionState(bp.name); 8679 final int flags = permissionState != null ? permissionState.getFlags() : 0; 8680 8681 if (origPermissions.revokeInstallPermission(bp) 8682 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 8683 // We will be transferring the permission flags, so clear them. 8684 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 8685 PackageManager.MASK_PERMISSION_FLAGS, 0); 8686 changedInstallPermission = true; 8687 } 8688 8689 // If the permission is not to be promoted to runtime we ignore it and 8690 // also its other flags as they are not applicable to install permissions. 8691 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 8692 for (int userId : currentUserIds) { 8693 if (permissionsState.grantRuntimePermission(bp, userId) != 8694 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8695 // Transfer the permission flags. 8696 permissionsState.updatePermissionFlags(bp, userId, 8697 flags, flags); 8698 // If we granted the permission, we have to write. 8699 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8700 changedRuntimePermissionUserIds, userId); 8701 } 8702 } 8703 } 8704 } break; 8705 8706 default: { 8707 if (packageOfInterest == null 8708 || packageOfInterest.equals(pkg.packageName)) { 8709 Slog.w(TAG, "Not granting permission " + perm 8710 + " to package " + pkg.packageName 8711 + " because it was previously installed without"); 8712 } 8713 } break; 8714 } 8715 } else { 8716 if (permissionsState.revokeInstallPermission(bp) != 8717 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8718 // Also drop the permission flags. 8719 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 8720 PackageManager.MASK_PERMISSION_FLAGS, 0); 8721 changedInstallPermission = true; 8722 Slog.i(TAG, "Un-granting permission " + perm 8723 + " from package " + pkg.packageName 8724 + " (protectionLevel=" + bp.protectionLevel 8725 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 8726 + ")"); 8727 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 8728 // Don't print warning for app op permissions, since it is fine for them 8729 // not to be granted, there is a UI for the user to decide. 8730 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 8731 Slog.w(TAG, "Not granting permission " + perm 8732 + " to package " + pkg.packageName 8733 + " (protectionLevel=" + bp.protectionLevel 8734 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 8735 + ")"); 8736 } 8737 } 8738 } 8739 } 8740 8741 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 8742 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 8743 // This is the first that we have heard about this package, so the 8744 // permissions we have now selected are fixed until explicitly 8745 // changed. 8746 ps.installPermissionsFixed = true; 8747 } 8748 8749 // Persist the runtime permissions state for users with changes. If permissions 8750 // were revoked because no app in the shared user declares them we have to 8751 // write synchronously to avoid losing runtime permissions state. 8752 for (int userId : changedRuntimePermissionUserIds) { 8753 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 8754 } 8755 8756 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8757 } 8758 8759 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 8760 boolean allowed = false; 8761 final int NP = PackageParser.NEW_PERMISSIONS.length; 8762 for (int ip=0; ip<NP; ip++) { 8763 final PackageParser.NewPermissionInfo npi 8764 = PackageParser.NEW_PERMISSIONS[ip]; 8765 if (npi.name.equals(perm) 8766 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 8767 allowed = true; 8768 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 8769 + pkg.packageName); 8770 break; 8771 } 8772 } 8773 return allowed; 8774 } 8775 8776 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 8777 BasePermission bp, PermissionsState origPermissions) { 8778 boolean allowed; 8779 allowed = (compareSignatures( 8780 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 8781 == PackageManager.SIGNATURE_MATCH) 8782 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 8783 == PackageManager.SIGNATURE_MATCH); 8784 if (!allowed && (bp.protectionLevel 8785 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 8786 if (isSystemApp(pkg)) { 8787 // For updated system applications, a system permission 8788 // is granted only if it had been defined by the original application. 8789 if (pkg.isUpdatedSystemApp()) { 8790 final PackageSetting sysPs = mSettings 8791 .getDisabledSystemPkgLPr(pkg.packageName); 8792 if (sysPs.getPermissionsState().hasInstallPermission(perm)) { 8793 // If the original was granted this permission, we take 8794 // that grant decision as read and propagate it to the 8795 // update. 8796 if (sysPs.isPrivileged()) { 8797 allowed = true; 8798 } 8799 } else { 8800 // The system apk may have been updated with an older 8801 // version of the one on the data partition, but which 8802 // granted a new system permission that it didn't have 8803 // before. In this case we do want to allow the app to 8804 // now get the new permission if the ancestral apk is 8805 // privileged to get it. 8806 if (sysPs.pkg != null && sysPs.isPrivileged()) { 8807 for (int j=0; 8808 j<sysPs.pkg.requestedPermissions.size(); j++) { 8809 if (perm.equals( 8810 sysPs.pkg.requestedPermissions.get(j))) { 8811 allowed = true; 8812 break; 8813 } 8814 } 8815 } 8816 } 8817 } else { 8818 allowed = isPrivilegedApp(pkg); 8819 } 8820 } 8821 } 8822 if (!allowed) { 8823 if (!allowed && (bp.protectionLevel 8824 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 8825 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 8826 // If this was a previously normal/dangerous permission that got moved 8827 // to a system permission as part of the runtime permission redesign, then 8828 // we still want to blindly grant it to old apps. 8829 allowed = true; 8830 } 8831 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 8832 && pkg.packageName.equals(mRequiredInstallerPackage)) { 8833 // If this permission is to be granted to the system installer and 8834 // this app is an installer, then it gets the permission. 8835 allowed = true; 8836 } 8837 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 8838 && pkg.packageName.equals(mRequiredVerifierPackage)) { 8839 // If this permission is to be granted to the system verifier and 8840 // this app is a verifier, then it gets the permission. 8841 allowed = true; 8842 } 8843 if (!allowed && (bp.protectionLevel 8844 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 8845 && isSystemApp(pkg)) { 8846 // Any pre-installed system app is allowed to get this permission. 8847 allowed = true; 8848 } 8849 if (!allowed && (bp.protectionLevel 8850 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 8851 // For development permissions, a development permission 8852 // is granted only if it was already granted. 8853 allowed = origPermissions.hasInstallPermission(perm); 8854 } 8855 } 8856 return allowed; 8857 } 8858 8859 final class ActivityIntentResolver 8860 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 8861 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8862 boolean defaultOnly, int userId) { 8863 if (!sUserManager.exists(userId)) return null; 8864 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8865 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8866 } 8867 8868 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8869 int userId) { 8870 if (!sUserManager.exists(userId)) return null; 8871 mFlags = flags; 8872 return super.queryIntent(intent, resolvedType, 8873 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8874 } 8875 8876 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8877 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 8878 if (!sUserManager.exists(userId)) return null; 8879 if (packageActivities == null) { 8880 return null; 8881 } 8882 mFlags = flags; 8883 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8884 final int N = packageActivities.size(); 8885 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 8886 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 8887 8888 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 8889 for (int i = 0; i < N; ++i) { 8890 intentFilters = packageActivities.get(i).intents; 8891 if (intentFilters != null && intentFilters.size() > 0) { 8892 PackageParser.ActivityIntentInfo[] array = 8893 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 8894 intentFilters.toArray(array); 8895 listCut.add(array); 8896 } 8897 } 8898 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8899 } 8900 8901 public final void addActivity(PackageParser.Activity a, String type) { 8902 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 8903 mActivities.put(a.getComponentName(), a); 8904 if (DEBUG_SHOW_INFO) 8905 Log.v( 8906 TAG, " " + type + " " + 8907 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 8908 if (DEBUG_SHOW_INFO) 8909 Log.v(TAG, " Class=" + a.info.name); 8910 final int NI = a.intents.size(); 8911 for (int j=0; j<NI; j++) { 8912 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 8913 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 8914 intent.setPriority(0); 8915 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 8916 + a.className + " with priority > 0, forcing to 0"); 8917 } 8918 if (DEBUG_SHOW_INFO) { 8919 Log.v(TAG, " IntentFilter:"); 8920 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8921 } 8922 if (!intent.debugCheck()) { 8923 Log.w(TAG, "==> For Activity " + a.info.name); 8924 } 8925 addFilter(intent); 8926 } 8927 } 8928 8929 public final void removeActivity(PackageParser.Activity a, String type) { 8930 mActivities.remove(a.getComponentName()); 8931 if (DEBUG_SHOW_INFO) { 8932 Log.v(TAG, " " + type + " " 8933 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 8934 : a.info.name) + ":"); 8935 Log.v(TAG, " Class=" + a.info.name); 8936 } 8937 final int NI = a.intents.size(); 8938 for (int j=0; j<NI; j++) { 8939 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 8940 if (DEBUG_SHOW_INFO) { 8941 Log.v(TAG, " IntentFilter:"); 8942 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8943 } 8944 removeFilter(intent); 8945 } 8946 } 8947 8948 @Override 8949 protected boolean allowFilterResult( 8950 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 8951 ActivityInfo filterAi = filter.activity.info; 8952 for (int i=dest.size()-1; i>=0; i--) { 8953 ActivityInfo destAi = dest.get(i).activityInfo; 8954 if (destAi.name == filterAi.name 8955 && destAi.packageName == filterAi.packageName) { 8956 return false; 8957 } 8958 } 8959 return true; 8960 } 8961 8962 @Override 8963 protected ActivityIntentInfo[] newArray(int size) { 8964 return new ActivityIntentInfo[size]; 8965 } 8966 8967 @Override 8968 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 8969 if (!sUserManager.exists(userId)) return true; 8970 PackageParser.Package p = filter.activity.owner; 8971 if (p != null) { 8972 PackageSetting ps = (PackageSetting)p.mExtras; 8973 if (ps != null) { 8974 // System apps are never considered stopped for purposes of 8975 // filtering, because there may be no way for the user to 8976 // actually re-launch them. 8977 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 8978 && ps.getStopped(userId); 8979 } 8980 } 8981 return false; 8982 } 8983 8984 @Override 8985 protected boolean isPackageForFilter(String packageName, 8986 PackageParser.ActivityIntentInfo info) { 8987 return packageName.equals(info.activity.owner.packageName); 8988 } 8989 8990 @Override 8991 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 8992 int match, int userId) { 8993 if (!sUserManager.exists(userId)) return null; 8994 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 8995 return null; 8996 } 8997 final PackageParser.Activity activity = info.activity; 8998 if (mSafeMode && (activity.info.applicationInfo.flags 8999 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9000 return null; 9001 } 9002 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 9003 if (ps == null) { 9004 return null; 9005 } 9006 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 9007 ps.readUserState(userId), userId); 9008 if (ai == null) { 9009 return null; 9010 } 9011 final ResolveInfo res = new ResolveInfo(); 9012 res.activityInfo = ai; 9013 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9014 res.filter = info; 9015 } 9016 if (info != null) { 9017 res.handleAllWebDataURI = info.handleAllWebDataURI(); 9018 } 9019 res.priority = info.getPriority(); 9020 res.preferredOrder = activity.owner.mPreferredOrder; 9021 //System.out.println("Result: " + res.activityInfo.className + 9022 // " = " + res.priority); 9023 res.match = match; 9024 res.isDefault = info.hasDefault; 9025 res.labelRes = info.labelRes; 9026 res.nonLocalizedLabel = info.nonLocalizedLabel; 9027 if (userNeedsBadging(userId)) { 9028 res.noResourceId = true; 9029 } else { 9030 res.icon = info.icon; 9031 } 9032 res.iconResourceId = info.icon; 9033 res.system = res.activityInfo.applicationInfo.isSystemApp(); 9034 return res; 9035 } 9036 9037 @Override 9038 protected void sortResults(List<ResolveInfo> results) { 9039 Collections.sort(results, mResolvePrioritySorter); 9040 } 9041 9042 @Override 9043 protected void dumpFilter(PrintWriter out, String prefix, 9044 PackageParser.ActivityIntentInfo filter) { 9045 out.print(prefix); out.print( 9046 Integer.toHexString(System.identityHashCode(filter.activity))); 9047 out.print(' '); 9048 filter.activity.printComponentShortName(out); 9049 out.print(" filter "); 9050 out.println(Integer.toHexString(System.identityHashCode(filter))); 9051 } 9052 9053 @Override 9054 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 9055 return filter.activity; 9056 } 9057 9058 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9059 PackageParser.Activity activity = (PackageParser.Activity)label; 9060 out.print(prefix); out.print( 9061 Integer.toHexString(System.identityHashCode(activity))); 9062 out.print(' '); 9063 activity.printComponentShortName(out); 9064 if (count > 1) { 9065 out.print(" ("); out.print(count); out.print(" filters)"); 9066 } 9067 out.println(); 9068 } 9069 9070// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9071// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9072// final List<ResolveInfo> retList = Lists.newArrayList(); 9073// while (i.hasNext()) { 9074// final ResolveInfo resolveInfo = i.next(); 9075// if (isEnabledLP(resolveInfo.activityInfo)) { 9076// retList.add(resolveInfo); 9077// } 9078// } 9079// return retList; 9080// } 9081 9082 // Keys are String (activity class name), values are Activity. 9083 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 9084 = new ArrayMap<ComponentName, PackageParser.Activity>(); 9085 private int mFlags; 9086 } 9087 9088 private final class ServiceIntentResolver 9089 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 9090 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9091 boolean defaultOnly, int userId) { 9092 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9093 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9094 } 9095 9096 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9097 int userId) { 9098 if (!sUserManager.exists(userId)) return null; 9099 mFlags = flags; 9100 return super.queryIntent(intent, resolvedType, 9101 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9102 } 9103 9104 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9105 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 9106 if (!sUserManager.exists(userId)) return null; 9107 if (packageServices == null) { 9108 return null; 9109 } 9110 mFlags = flags; 9111 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9112 final int N = packageServices.size(); 9113 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 9114 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 9115 9116 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 9117 for (int i = 0; i < N; ++i) { 9118 intentFilters = packageServices.get(i).intents; 9119 if (intentFilters != null && intentFilters.size() > 0) { 9120 PackageParser.ServiceIntentInfo[] array = 9121 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 9122 intentFilters.toArray(array); 9123 listCut.add(array); 9124 } 9125 } 9126 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9127 } 9128 9129 public final void addService(PackageParser.Service s) { 9130 mServices.put(s.getComponentName(), s); 9131 if (DEBUG_SHOW_INFO) { 9132 Log.v(TAG, " " 9133 + (s.info.nonLocalizedLabel != null 9134 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9135 Log.v(TAG, " Class=" + s.info.name); 9136 } 9137 final int NI = s.intents.size(); 9138 int j; 9139 for (j=0; j<NI; j++) { 9140 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9141 if (DEBUG_SHOW_INFO) { 9142 Log.v(TAG, " IntentFilter:"); 9143 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9144 } 9145 if (!intent.debugCheck()) { 9146 Log.w(TAG, "==> For Service " + s.info.name); 9147 } 9148 addFilter(intent); 9149 } 9150 } 9151 9152 public final void removeService(PackageParser.Service s) { 9153 mServices.remove(s.getComponentName()); 9154 if (DEBUG_SHOW_INFO) { 9155 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 9156 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9157 Log.v(TAG, " Class=" + s.info.name); 9158 } 9159 final int NI = s.intents.size(); 9160 int j; 9161 for (j=0; j<NI; j++) { 9162 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9163 if (DEBUG_SHOW_INFO) { 9164 Log.v(TAG, " IntentFilter:"); 9165 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9166 } 9167 removeFilter(intent); 9168 } 9169 } 9170 9171 @Override 9172 protected boolean allowFilterResult( 9173 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 9174 ServiceInfo filterSi = filter.service.info; 9175 for (int i=dest.size()-1; i>=0; i--) { 9176 ServiceInfo destAi = dest.get(i).serviceInfo; 9177 if (destAi.name == filterSi.name 9178 && destAi.packageName == filterSi.packageName) { 9179 return false; 9180 } 9181 } 9182 return true; 9183 } 9184 9185 @Override 9186 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 9187 return new PackageParser.ServiceIntentInfo[size]; 9188 } 9189 9190 @Override 9191 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 9192 if (!sUserManager.exists(userId)) return true; 9193 PackageParser.Package p = filter.service.owner; 9194 if (p != null) { 9195 PackageSetting ps = (PackageSetting)p.mExtras; 9196 if (ps != null) { 9197 // System apps are never considered stopped for purposes of 9198 // filtering, because there may be no way for the user to 9199 // actually re-launch them. 9200 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9201 && ps.getStopped(userId); 9202 } 9203 } 9204 return false; 9205 } 9206 9207 @Override 9208 protected boolean isPackageForFilter(String packageName, 9209 PackageParser.ServiceIntentInfo info) { 9210 return packageName.equals(info.service.owner.packageName); 9211 } 9212 9213 @Override 9214 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 9215 int match, int userId) { 9216 if (!sUserManager.exists(userId)) return null; 9217 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 9218 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 9219 return null; 9220 } 9221 final PackageParser.Service service = info.service; 9222 if (mSafeMode && (service.info.applicationInfo.flags 9223 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9224 return null; 9225 } 9226 PackageSetting ps = (PackageSetting) service.owner.mExtras; 9227 if (ps == null) { 9228 return null; 9229 } 9230 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 9231 ps.readUserState(userId), userId); 9232 if (si == null) { 9233 return null; 9234 } 9235 final ResolveInfo res = new ResolveInfo(); 9236 res.serviceInfo = si; 9237 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9238 res.filter = filter; 9239 } 9240 res.priority = info.getPriority(); 9241 res.preferredOrder = service.owner.mPreferredOrder; 9242 res.match = match; 9243 res.isDefault = info.hasDefault; 9244 res.labelRes = info.labelRes; 9245 res.nonLocalizedLabel = info.nonLocalizedLabel; 9246 res.icon = info.icon; 9247 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 9248 return res; 9249 } 9250 9251 @Override 9252 protected void sortResults(List<ResolveInfo> results) { 9253 Collections.sort(results, mResolvePrioritySorter); 9254 } 9255 9256 @Override 9257 protected void dumpFilter(PrintWriter out, String prefix, 9258 PackageParser.ServiceIntentInfo filter) { 9259 out.print(prefix); out.print( 9260 Integer.toHexString(System.identityHashCode(filter.service))); 9261 out.print(' '); 9262 filter.service.printComponentShortName(out); 9263 out.print(" filter "); 9264 out.println(Integer.toHexString(System.identityHashCode(filter))); 9265 } 9266 9267 @Override 9268 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 9269 return filter.service; 9270 } 9271 9272 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9273 PackageParser.Service service = (PackageParser.Service)label; 9274 out.print(prefix); out.print( 9275 Integer.toHexString(System.identityHashCode(service))); 9276 out.print(' '); 9277 service.printComponentShortName(out); 9278 if (count > 1) { 9279 out.print(" ("); out.print(count); out.print(" filters)"); 9280 } 9281 out.println(); 9282 } 9283 9284// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9285// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9286// final List<ResolveInfo> retList = Lists.newArrayList(); 9287// while (i.hasNext()) { 9288// final ResolveInfo resolveInfo = (ResolveInfo) i; 9289// if (isEnabledLP(resolveInfo.serviceInfo)) { 9290// retList.add(resolveInfo); 9291// } 9292// } 9293// return retList; 9294// } 9295 9296 // Keys are String (activity class name), values are Activity. 9297 private final ArrayMap<ComponentName, PackageParser.Service> mServices 9298 = new ArrayMap<ComponentName, PackageParser.Service>(); 9299 private int mFlags; 9300 }; 9301 9302 private final class ProviderIntentResolver 9303 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 9304 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9305 boolean defaultOnly, int userId) { 9306 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9307 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9308 } 9309 9310 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9311 int userId) { 9312 if (!sUserManager.exists(userId)) 9313 return null; 9314 mFlags = flags; 9315 return super.queryIntent(intent, resolvedType, 9316 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9317 } 9318 9319 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9320 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 9321 if (!sUserManager.exists(userId)) 9322 return null; 9323 if (packageProviders == null) { 9324 return null; 9325 } 9326 mFlags = flags; 9327 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 9328 final int N = packageProviders.size(); 9329 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 9330 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 9331 9332 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 9333 for (int i = 0; i < N; ++i) { 9334 intentFilters = packageProviders.get(i).intents; 9335 if (intentFilters != null && intentFilters.size() > 0) { 9336 PackageParser.ProviderIntentInfo[] array = 9337 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 9338 intentFilters.toArray(array); 9339 listCut.add(array); 9340 } 9341 } 9342 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9343 } 9344 9345 public final void addProvider(PackageParser.Provider p) { 9346 if (mProviders.containsKey(p.getComponentName())) { 9347 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 9348 return; 9349 } 9350 9351 mProviders.put(p.getComponentName(), p); 9352 if (DEBUG_SHOW_INFO) { 9353 Log.v(TAG, " " 9354 + (p.info.nonLocalizedLabel != null 9355 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 9356 Log.v(TAG, " Class=" + p.info.name); 9357 } 9358 final int NI = p.intents.size(); 9359 int j; 9360 for (j = 0; j < NI; j++) { 9361 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 9362 if (DEBUG_SHOW_INFO) { 9363 Log.v(TAG, " IntentFilter:"); 9364 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9365 } 9366 if (!intent.debugCheck()) { 9367 Log.w(TAG, "==> For Provider " + p.info.name); 9368 } 9369 addFilter(intent); 9370 } 9371 } 9372 9373 public final void removeProvider(PackageParser.Provider p) { 9374 mProviders.remove(p.getComponentName()); 9375 if (DEBUG_SHOW_INFO) { 9376 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 9377 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 9378 Log.v(TAG, " Class=" + p.info.name); 9379 } 9380 final int NI = p.intents.size(); 9381 int j; 9382 for (j = 0; j < NI; j++) { 9383 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 9384 if (DEBUG_SHOW_INFO) { 9385 Log.v(TAG, " IntentFilter:"); 9386 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9387 } 9388 removeFilter(intent); 9389 } 9390 } 9391 9392 @Override 9393 protected boolean allowFilterResult( 9394 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 9395 ProviderInfo filterPi = filter.provider.info; 9396 for (int i = dest.size() - 1; i >= 0; i--) { 9397 ProviderInfo destPi = dest.get(i).providerInfo; 9398 if (destPi.name == filterPi.name 9399 && destPi.packageName == filterPi.packageName) { 9400 return false; 9401 } 9402 } 9403 return true; 9404 } 9405 9406 @Override 9407 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 9408 return new PackageParser.ProviderIntentInfo[size]; 9409 } 9410 9411 @Override 9412 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 9413 if (!sUserManager.exists(userId)) 9414 return true; 9415 PackageParser.Package p = filter.provider.owner; 9416 if (p != null) { 9417 PackageSetting ps = (PackageSetting) p.mExtras; 9418 if (ps != null) { 9419 // System apps are never considered stopped for purposes of 9420 // filtering, because there may be no way for the user to 9421 // actually re-launch them. 9422 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9423 && ps.getStopped(userId); 9424 } 9425 } 9426 return false; 9427 } 9428 9429 @Override 9430 protected boolean isPackageForFilter(String packageName, 9431 PackageParser.ProviderIntentInfo info) { 9432 return packageName.equals(info.provider.owner.packageName); 9433 } 9434 9435 @Override 9436 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 9437 int match, int userId) { 9438 if (!sUserManager.exists(userId)) 9439 return null; 9440 final PackageParser.ProviderIntentInfo info = filter; 9441 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 9442 return null; 9443 } 9444 final PackageParser.Provider provider = info.provider; 9445 if (mSafeMode && (provider.info.applicationInfo.flags 9446 & ApplicationInfo.FLAG_SYSTEM) == 0) { 9447 return null; 9448 } 9449 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 9450 if (ps == null) { 9451 return null; 9452 } 9453 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 9454 ps.readUserState(userId), userId); 9455 if (pi == null) { 9456 return null; 9457 } 9458 final ResolveInfo res = new ResolveInfo(); 9459 res.providerInfo = pi; 9460 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 9461 res.filter = filter; 9462 } 9463 res.priority = info.getPriority(); 9464 res.preferredOrder = provider.owner.mPreferredOrder; 9465 res.match = match; 9466 res.isDefault = info.hasDefault; 9467 res.labelRes = info.labelRes; 9468 res.nonLocalizedLabel = info.nonLocalizedLabel; 9469 res.icon = info.icon; 9470 res.system = res.providerInfo.applicationInfo.isSystemApp(); 9471 return res; 9472 } 9473 9474 @Override 9475 protected void sortResults(List<ResolveInfo> results) { 9476 Collections.sort(results, mResolvePrioritySorter); 9477 } 9478 9479 @Override 9480 protected void dumpFilter(PrintWriter out, String prefix, 9481 PackageParser.ProviderIntentInfo filter) { 9482 out.print(prefix); 9483 out.print( 9484 Integer.toHexString(System.identityHashCode(filter.provider))); 9485 out.print(' '); 9486 filter.provider.printComponentShortName(out); 9487 out.print(" filter "); 9488 out.println(Integer.toHexString(System.identityHashCode(filter))); 9489 } 9490 9491 @Override 9492 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 9493 return filter.provider; 9494 } 9495 9496 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9497 PackageParser.Provider provider = (PackageParser.Provider)label; 9498 out.print(prefix); out.print( 9499 Integer.toHexString(System.identityHashCode(provider))); 9500 out.print(' '); 9501 provider.printComponentShortName(out); 9502 if (count > 1) { 9503 out.print(" ("); out.print(count); out.print(" filters)"); 9504 } 9505 out.println(); 9506 } 9507 9508 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 9509 = new ArrayMap<ComponentName, PackageParser.Provider>(); 9510 private int mFlags; 9511 }; 9512 9513 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 9514 new Comparator<ResolveInfo>() { 9515 public int compare(ResolveInfo r1, ResolveInfo r2) { 9516 int v1 = r1.priority; 9517 int v2 = r2.priority; 9518 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 9519 if (v1 != v2) { 9520 return (v1 > v2) ? -1 : 1; 9521 } 9522 v1 = r1.preferredOrder; 9523 v2 = r2.preferredOrder; 9524 if (v1 != v2) { 9525 return (v1 > v2) ? -1 : 1; 9526 } 9527 if (r1.isDefault != r2.isDefault) { 9528 return r1.isDefault ? -1 : 1; 9529 } 9530 v1 = r1.match; 9531 v2 = r2.match; 9532 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 9533 if (v1 != v2) { 9534 return (v1 > v2) ? -1 : 1; 9535 } 9536 if (r1.system != r2.system) { 9537 return r1.system ? -1 : 1; 9538 } 9539 return 0; 9540 } 9541 }; 9542 9543 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 9544 new Comparator<ProviderInfo>() { 9545 public int compare(ProviderInfo p1, ProviderInfo p2) { 9546 final int v1 = p1.initOrder; 9547 final int v2 = p2.initOrder; 9548 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 9549 } 9550 }; 9551 9552 final void sendPackageBroadcast(final String action, final String pkg, 9553 final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver, 9554 final int[] userIds) { 9555 mHandler.post(new Runnable() { 9556 @Override 9557 public void run() { 9558 try { 9559 final IActivityManager am = ActivityManagerNative.getDefault(); 9560 if (am == null) return; 9561 final int[] resolvedUserIds; 9562 if (userIds == null) { 9563 resolvedUserIds = am.getRunningUserIds(); 9564 } else { 9565 resolvedUserIds = userIds; 9566 } 9567 for (int id : resolvedUserIds) { 9568 final Intent intent = new Intent(action, 9569 pkg != null ? Uri.fromParts("package", pkg, null) : null); 9570 if (extras != null) { 9571 intent.putExtras(extras); 9572 } 9573 if (targetPkg != null) { 9574 intent.setPackage(targetPkg); 9575 } 9576 // Modify the UID when posting to other users 9577 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 9578 if (uid > 0 && UserHandle.getUserId(uid) != id) { 9579 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 9580 intent.putExtra(Intent.EXTRA_UID, uid); 9581 } 9582 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 9583 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 9584 if (DEBUG_BROADCASTS) { 9585 RuntimeException here = new RuntimeException("here"); 9586 here.fillInStackTrace(); 9587 Slog.d(TAG, "Sending to user " + id + ": " 9588 + intent.toShortString(false, true, false, false) 9589 + " " + intent.getExtras(), here); 9590 } 9591 am.broadcastIntent(null, intent, null, finishedReceiver, 9592 0, null, null, null, android.app.AppOpsManager.OP_NONE, 9593 null, finishedReceiver != null, false, id); 9594 } 9595 } catch (RemoteException ex) { 9596 } 9597 } 9598 }); 9599 } 9600 9601 /** 9602 * Check if the external storage media is available. This is true if there 9603 * is a mounted external storage medium or if the external storage is 9604 * emulated. 9605 */ 9606 private boolean isExternalMediaAvailable() { 9607 return mMediaMounted || Environment.isExternalStorageEmulated(); 9608 } 9609 9610 @Override 9611 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 9612 // writer 9613 synchronized (mPackages) { 9614 if (!isExternalMediaAvailable()) { 9615 // If the external storage is no longer mounted at this point, 9616 // the caller may not have been able to delete all of this 9617 // packages files and can not delete any more. Bail. 9618 return null; 9619 } 9620 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 9621 if (lastPackage != null) { 9622 pkgs.remove(lastPackage); 9623 } 9624 if (pkgs.size() > 0) { 9625 return pkgs.get(0); 9626 } 9627 } 9628 return null; 9629 } 9630 9631 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 9632 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 9633 userId, andCode ? 1 : 0, packageName); 9634 if (mSystemReady) { 9635 msg.sendToTarget(); 9636 } else { 9637 if (mPostSystemReadyMessages == null) { 9638 mPostSystemReadyMessages = new ArrayList<>(); 9639 } 9640 mPostSystemReadyMessages.add(msg); 9641 } 9642 } 9643 9644 void startCleaningPackages() { 9645 // reader 9646 synchronized (mPackages) { 9647 if (!isExternalMediaAvailable()) { 9648 return; 9649 } 9650 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 9651 return; 9652 } 9653 } 9654 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 9655 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 9656 IActivityManager am = ActivityManagerNative.getDefault(); 9657 if (am != null) { 9658 try { 9659 am.startService(null, intent, null, mContext.getOpPackageName(), 9660 UserHandle.USER_SYSTEM); 9661 } catch (RemoteException e) { 9662 } 9663 } 9664 } 9665 9666 @Override 9667 public void installPackage(String originPath, IPackageInstallObserver2 observer, 9668 int installFlags, String installerPackageName, VerificationParams verificationParams, 9669 String packageAbiOverride) { 9670 installPackageAsUser(originPath, observer, installFlags, installerPackageName, 9671 verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); 9672 } 9673 9674 @Override 9675 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 9676 int installFlags, String installerPackageName, VerificationParams verificationParams, 9677 String packageAbiOverride, int userId) { 9678 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 9679 9680 final int callingUid = Binder.getCallingUid(); 9681 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 9682 9683 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 9684 try { 9685 if (observer != null) { 9686 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 9687 } 9688 } catch (RemoteException re) { 9689 } 9690 return; 9691 } 9692 9693 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 9694 installFlags |= PackageManager.INSTALL_FROM_ADB; 9695 9696 } else { 9697 // Caller holds INSTALL_PACKAGES permission, so we're less strict 9698 // about installerPackageName. 9699 9700 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 9701 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 9702 } 9703 9704 UserHandle user; 9705 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 9706 user = UserHandle.ALL; 9707 } else { 9708 user = new UserHandle(userId); 9709 } 9710 9711 // Only system components can circumvent runtime permissions when installing. 9712 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 9713 && mContext.checkCallingOrSelfPermission(Manifest.permission 9714 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 9715 throw new SecurityException("You need the " 9716 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 9717 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 9718 } 9719 9720 verificationParams.setInstallerUid(callingUid); 9721 9722 final File originFile = new File(originPath); 9723 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 9724 9725 final Message msg = mHandler.obtainMessage(INIT_COPY); 9726 final InstallParams params = new InstallParams(origin, null, observer, installFlags, 9727 installerPackageName, null, verificationParams, user, packageAbiOverride, null); 9728 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 9729 msg.obj = params; 9730 9731 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 9732 System.identityHashCode(msg.obj)); 9733 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 9734 System.identityHashCode(msg.obj)); 9735 9736 mHandler.sendMessage(msg); 9737 } 9738 9739 void installStage(String packageName, File stagedDir, String stagedCid, 9740 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 9741 String installerPackageName, int installerUid, UserHandle user) { 9742 final VerificationParams verifParams = new VerificationParams( 9743 null, sessionParams.originatingUri, sessionParams.referrerUri, 9744 sessionParams.originatingUid, null); 9745 verifParams.setInstallerUid(installerUid); 9746 9747 final OriginInfo origin; 9748 if (stagedDir != null) { 9749 origin = OriginInfo.fromStagedFile(stagedDir); 9750 } else { 9751 origin = OriginInfo.fromStagedContainer(stagedCid); 9752 } 9753 9754 final Message msg = mHandler.obtainMessage(INIT_COPY); 9755 final InstallParams params = new InstallParams(origin, null, observer, 9756 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 9757 verifParams, user, sessionParams.abiOverride, 9758 sessionParams.grantedRuntimePermissions); 9759 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 9760 msg.obj = params; 9761 9762 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 9763 System.identityHashCode(msg.obj)); 9764 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 9765 System.identityHashCode(msg.obj)); 9766 9767 mHandler.sendMessage(msg); 9768 } 9769 9770 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 9771 Bundle extras = new Bundle(1); 9772 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 9773 9774 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 9775 packageName, extras, null, null, new int[] {userId}); 9776 try { 9777 IActivityManager am = ActivityManagerNative.getDefault(); 9778 final boolean isSystem = 9779 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 9780 if (isSystem && am.isUserRunning(userId, false)) { 9781 // The just-installed/enabled app is bundled on the system, so presumed 9782 // to be able to run automatically without needing an explicit launch. 9783 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 9784 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 9785 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 9786 .setPackage(packageName); 9787 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 9788 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 9789 } 9790 } catch (RemoteException e) { 9791 // shouldn't happen 9792 Slog.w(TAG, "Unable to bootstrap installed package", e); 9793 } 9794 } 9795 9796 @Override 9797 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 9798 int userId) { 9799 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9800 PackageSetting pkgSetting; 9801 final int uid = Binder.getCallingUid(); 9802 enforceCrossUserPermission(uid, userId, true, true, 9803 "setApplicationHiddenSetting for user " + userId); 9804 9805 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 9806 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 9807 return false; 9808 } 9809 9810 long callingId = Binder.clearCallingIdentity(); 9811 try { 9812 boolean sendAdded = false; 9813 boolean sendRemoved = false; 9814 // writer 9815 synchronized (mPackages) { 9816 pkgSetting = mSettings.mPackages.get(packageName); 9817 if (pkgSetting == null) { 9818 return false; 9819 } 9820 if (pkgSetting.getHidden(userId) != hidden) { 9821 pkgSetting.setHidden(hidden, userId); 9822 mSettings.writePackageRestrictionsLPr(userId); 9823 if (hidden) { 9824 sendRemoved = true; 9825 } else { 9826 sendAdded = true; 9827 } 9828 } 9829 } 9830 if (sendAdded) { 9831 sendPackageAddedForUser(packageName, pkgSetting, userId); 9832 return true; 9833 } 9834 if (sendRemoved) { 9835 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 9836 "hiding pkg"); 9837 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 9838 return true; 9839 } 9840 } finally { 9841 Binder.restoreCallingIdentity(callingId); 9842 } 9843 return false; 9844 } 9845 9846 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 9847 int userId) { 9848 final PackageRemovedInfo info = new PackageRemovedInfo(); 9849 info.removedPackage = packageName; 9850 info.removedUsers = new int[] {userId}; 9851 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 9852 info.sendBroadcast(false, false, false); 9853 } 9854 9855 /** 9856 * Returns true if application is not found or there was an error. Otherwise it returns 9857 * the hidden state of the package for the given user. 9858 */ 9859 @Override 9860 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 9861 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9862 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 9863 false, "getApplicationHidden for user " + userId); 9864 PackageSetting pkgSetting; 9865 long callingId = Binder.clearCallingIdentity(); 9866 try { 9867 // writer 9868 synchronized (mPackages) { 9869 pkgSetting = mSettings.mPackages.get(packageName); 9870 if (pkgSetting == null) { 9871 return true; 9872 } 9873 return pkgSetting.getHidden(userId); 9874 } 9875 } finally { 9876 Binder.restoreCallingIdentity(callingId); 9877 } 9878 } 9879 9880 /** 9881 * @hide 9882 */ 9883 @Override 9884 public int installExistingPackageAsUser(String packageName, int userId) { 9885 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 9886 null); 9887 PackageSetting pkgSetting; 9888 final int uid = Binder.getCallingUid(); 9889 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 9890 + userId); 9891 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 9892 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 9893 } 9894 9895 long callingId = Binder.clearCallingIdentity(); 9896 try { 9897 boolean sendAdded = false; 9898 9899 // writer 9900 synchronized (mPackages) { 9901 pkgSetting = mSettings.mPackages.get(packageName); 9902 if (pkgSetting == null) { 9903 return PackageManager.INSTALL_FAILED_INVALID_URI; 9904 } 9905 if (!pkgSetting.getInstalled(userId)) { 9906 pkgSetting.setInstalled(true, userId); 9907 pkgSetting.setHidden(false, userId); 9908 mSettings.writePackageRestrictionsLPr(userId); 9909 sendAdded = true; 9910 } 9911 } 9912 9913 if (sendAdded) { 9914 sendPackageAddedForUser(packageName, pkgSetting, userId); 9915 } 9916 } finally { 9917 Binder.restoreCallingIdentity(callingId); 9918 } 9919 9920 return PackageManager.INSTALL_SUCCEEDED; 9921 } 9922 9923 boolean isUserRestricted(int userId, String restrictionKey) { 9924 Bundle restrictions = sUserManager.getUserRestrictions(userId); 9925 if (restrictions.getBoolean(restrictionKey, false)) { 9926 Log.w(TAG, "User is restricted: " + restrictionKey); 9927 return true; 9928 } 9929 return false; 9930 } 9931 9932 @Override 9933 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 9934 mContext.enforceCallingOrSelfPermission( 9935 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9936 "Only package verification agents can verify applications"); 9937 9938 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 9939 final PackageVerificationResponse response = new PackageVerificationResponse( 9940 verificationCode, Binder.getCallingUid()); 9941 msg.arg1 = id; 9942 msg.obj = response; 9943 mHandler.sendMessage(msg); 9944 } 9945 9946 @Override 9947 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 9948 long millisecondsToDelay) { 9949 mContext.enforceCallingOrSelfPermission( 9950 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9951 "Only package verification agents can extend verification timeouts"); 9952 9953 final PackageVerificationState state = mPendingVerification.get(id); 9954 final PackageVerificationResponse response = new PackageVerificationResponse( 9955 verificationCodeAtTimeout, Binder.getCallingUid()); 9956 9957 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 9958 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 9959 } 9960 if (millisecondsToDelay < 0) { 9961 millisecondsToDelay = 0; 9962 } 9963 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 9964 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 9965 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 9966 } 9967 9968 if ((state != null) && !state.timeoutExtended()) { 9969 state.extendTimeout(); 9970 9971 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 9972 msg.arg1 = id; 9973 msg.obj = response; 9974 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 9975 } 9976 } 9977 9978 private void broadcastPackageVerified(int verificationId, Uri packageUri, 9979 int verificationCode, UserHandle user) { 9980 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 9981 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 9982 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 9983 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 9984 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 9985 9986 mContext.sendBroadcastAsUser(intent, user, 9987 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 9988 } 9989 9990 private ComponentName matchComponentForVerifier(String packageName, 9991 List<ResolveInfo> receivers) { 9992 ActivityInfo targetReceiver = null; 9993 9994 final int NR = receivers.size(); 9995 for (int i = 0; i < NR; i++) { 9996 final ResolveInfo info = receivers.get(i); 9997 if (info.activityInfo == null) { 9998 continue; 9999 } 10000 10001 if (packageName.equals(info.activityInfo.packageName)) { 10002 targetReceiver = info.activityInfo; 10003 break; 10004 } 10005 } 10006 10007 if (targetReceiver == null) { 10008 return null; 10009 } 10010 10011 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 10012 } 10013 10014 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 10015 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 10016 if (pkgInfo.verifiers.length == 0) { 10017 return null; 10018 } 10019 10020 final int N = pkgInfo.verifiers.length; 10021 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 10022 for (int i = 0; i < N; i++) { 10023 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 10024 10025 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 10026 receivers); 10027 if (comp == null) { 10028 continue; 10029 } 10030 10031 final int verifierUid = getUidForVerifier(verifierInfo); 10032 if (verifierUid == -1) { 10033 continue; 10034 } 10035 10036 if (DEBUG_VERIFY) { 10037 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 10038 + " with the correct signature"); 10039 } 10040 sufficientVerifiers.add(comp); 10041 verificationState.addSufficientVerifier(verifierUid); 10042 } 10043 10044 return sufficientVerifiers; 10045 } 10046 10047 private int getUidForVerifier(VerifierInfo verifierInfo) { 10048 synchronized (mPackages) { 10049 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 10050 if (pkg == null) { 10051 return -1; 10052 } else if (pkg.mSignatures.length != 1) { 10053 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10054 + " has more than one signature; ignoring"); 10055 return -1; 10056 } 10057 10058 /* 10059 * If the public key of the package's signature does not match 10060 * our expected public key, then this is a different package and 10061 * we should skip. 10062 */ 10063 10064 final byte[] expectedPublicKey; 10065 try { 10066 final Signature verifierSig = pkg.mSignatures[0]; 10067 final PublicKey publicKey = verifierSig.getPublicKey(); 10068 expectedPublicKey = publicKey.getEncoded(); 10069 } catch (CertificateException e) { 10070 return -1; 10071 } 10072 10073 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 10074 10075 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 10076 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10077 + " does not have the expected public key; ignoring"); 10078 return -1; 10079 } 10080 10081 return pkg.applicationInfo.uid; 10082 } 10083 } 10084 10085 @Override 10086 public void finishPackageInstall(int token) { 10087 enforceSystemOrRoot("Only the system is allowed to finish installs"); 10088 10089 if (DEBUG_INSTALL) { 10090 Slog.v(TAG, "BM finishing package install for " + token); 10091 } 10092 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 10093 10094 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 10095 mHandler.sendMessage(msg); 10096 } 10097 10098 /** 10099 * Get the verification agent timeout. 10100 * 10101 * @return verification timeout in milliseconds 10102 */ 10103 private long getVerificationTimeout() { 10104 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 10105 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 10106 DEFAULT_VERIFICATION_TIMEOUT); 10107 } 10108 10109 /** 10110 * Get the default verification agent response code. 10111 * 10112 * @return default verification response code 10113 */ 10114 private int getDefaultVerificationResponse() { 10115 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10116 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 10117 DEFAULT_VERIFICATION_RESPONSE); 10118 } 10119 10120 /** 10121 * Check whether or not package verification has been enabled. 10122 * 10123 * @return true if verification should be performed 10124 */ 10125 private boolean isVerificationEnabled(int userId, int installFlags) { 10126 if (!DEFAULT_VERIFY_ENABLE) { 10127 return false; 10128 } 10129 // TODO: fix b/25118622; don't bypass verification 10130 if (Build.IS_DEBUGGABLE && (installFlags & PackageManager.INSTALL_QUICK) != 0) { 10131 return false; 10132 } 10133 10134 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 10135 10136 // Check if installing from ADB 10137 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 10138 // Do not run verification in a test harness environment 10139 if (ActivityManager.isRunningInTestHarness()) { 10140 return false; 10141 } 10142 if (ensureVerifyAppsEnabled) { 10143 return true; 10144 } 10145 // Check if the developer does not want package verification for ADB installs 10146 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10147 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 10148 return false; 10149 } 10150 } 10151 10152 if (ensureVerifyAppsEnabled) { 10153 return true; 10154 } 10155 10156 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10157 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 10158 } 10159 10160 @Override 10161 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 10162 throws RemoteException { 10163 mContext.enforceCallingOrSelfPermission( 10164 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 10165 "Only intentfilter verification agents can verify applications"); 10166 10167 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 10168 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 10169 Binder.getCallingUid(), verificationCode, failedDomains); 10170 msg.arg1 = id; 10171 msg.obj = response; 10172 mHandler.sendMessage(msg); 10173 } 10174 10175 @Override 10176 public int getIntentVerificationStatus(String packageName, int userId) { 10177 synchronized (mPackages) { 10178 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 10179 } 10180 } 10181 10182 @Override 10183 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 10184 mContext.enforceCallingOrSelfPermission( 10185 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10186 10187 boolean result = false; 10188 synchronized (mPackages) { 10189 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 10190 } 10191 if (result) { 10192 scheduleWritePackageRestrictionsLocked(userId); 10193 } 10194 return result; 10195 } 10196 10197 @Override 10198 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 10199 synchronized (mPackages) { 10200 return mSettings.getIntentFilterVerificationsLPr(packageName); 10201 } 10202 } 10203 10204 @Override 10205 public List<IntentFilter> getAllIntentFilters(String packageName) { 10206 if (TextUtils.isEmpty(packageName)) { 10207 return Collections.<IntentFilter>emptyList(); 10208 } 10209 synchronized (mPackages) { 10210 PackageParser.Package pkg = mPackages.get(packageName); 10211 if (pkg == null || pkg.activities == null) { 10212 return Collections.<IntentFilter>emptyList(); 10213 } 10214 final int count = pkg.activities.size(); 10215 ArrayList<IntentFilter> result = new ArrayList<>(); 10216 for (int n=0; n<count; n++) { 10217 PackageParser.Activity activity = pkg.activities.get(n); 10218 if (activity.intents != null || activity.intents.size() > 0) { 10219 result.addAll(activity.intents); 10220 } 10221 } 10222 return result; 10223 } 10224 } 10225 10226 @Override 10227 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 10228 mContext.enforceCallingOrSelfPermission( 10229 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10230 10231 synchronized (mPackages) { 10232 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 10233 if (packageName != null) { 10234 result |= updateIntentVerificationStatus(packageName, 10235 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 10236 userId); 10237 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 10238 packageName, userId); 10239 } 10240 return result; 10241 } 10242 } 10243 10244 @Override 10245 public String getDefaultBrowserPackageName(int userId) { 10246 synchronized (mPackages) { 10247 return mSettings.getDefaultBrowserPackageNameLPw(userId); 10248 } 10249 } 10250 10251 /** 10252 * Get the "allow unknown sources" setting. 10253 * 10254 * @return the current "allow unknown sources" setting 10255 */ 10256 private int getUnknownSourcesSettings() { 10257 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10258 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 10259 -1); 10260 } 10261 10262 @Override 10263 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 10264 final int uid = Binder.getCallingUid(); 10265 // writer 10266 synchronized (mPackages) { 10267 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 10268 if (targetPackageSetting == null) { 10269 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 10270 } 10271 10272 PackageSetting installerPackageSetting; 10273 if (installerPackageName != null) { 10274 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 10275 if (installerPackageSetting == null) { 10276 throw new IllegalArgumentException("Unknown installer package: " 10277 + installerPackageName); 10278 } 10279 } else { 10280 installerPackageSetting = null; 10281 } 10282 10283 Signature[] callerSignature; 10284 Object obj = mSettings.getUserIdLPr(uid); 10285 if (obj != null) { 10286 if (obj instanceof SharedUserSetting) { 10287 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 10288 } else if (obj instanceof PackageSetting) { 10289 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 10290 } else { 10291 throw new SecurityException("Bad object " + obj + " for uid " + uid); 10292 } 10293 } else { 10294 throw new SecurityException("Unknown calling uid " + uid); 10295 } 10296 10297 // Verify: can't set installerPackageName to a package that is 10298 // not signed with the same cert as the caller. 10299 if (installerPackageSetting != null) { 10300 if (compareSignatures(callerSignature, 10301 installerPackageSetting.signatures.mSignatures) 10302 != PackageManager.SIGNATURE_MATCH) { 10303 throw new SecurityException( 10304 "Caller does not have same cert as new installer package " 10305 + installerPackageName); 10306 } 10307 } 10308 10309 // Verify: if target already has an installer package, it must 10310 // be signed with the same cert as the caller. 10311 if (targetPackageSetting.installerPackageName != null) { 10312 PackageSetting setting = mSettings.mPackages.get( 10313 targetPackageSetting.installerPackageName); 10314 // If the currently set package isn't valid, then it's always 10315 // okay to change it. 10316 if (setting != null) { 10317 if (compareSignatures(callerSignature, 10318 setting.signatures.mSignatures) 10319 != PackageManager.SIGNATURE_MATCH) { 10320 throw new SecurityException( 10321 "Caller does not have same cert as old installer package " 10322 + targetPackageSetting.installerPackageName); 10323 } 10324 } 10325 } 10326 10327 // Okay! 10328 targetPackageSetting.installerPackageName = installerPackageName; 10329 scheduleWriteSettingsLocked(); 10330 } 10331 } 10332 10333 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 10334 // Queue up an async operation since the package installation may take a little while. 10335 mHandler.post(new Runnable() { 10336 public void run() { 10337 mHandler.removeCallbacks(this); 10338 // Result object to be returned 10339 PackageInstalledInfo res = new PackageInstalledInfo(); 10340 res.returnCode = currentStatus; 10341 res.uid = -1; 10342 res.pkg = null; 10343 res.removedInfo = new PackageRemovedInfo(); 10344 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 10345 args.doPreInstall(res.returnCode); 10346 synchronized (mInstallLock) { 10347 installPackageTracedLI(args, res); 10348 } 10349 args.doPostInstall(res.returnCode, res.uid); 10350 } 10351 10352 // A restore should be performed at this point if (a) the install 10353 // succeeded, (b) the operation is not an update, and (c) the new 10354 // package has not opted out of backup participation. 10355 final boolean update = res.removedInfo.removedPackage != null; 10356 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 10357 boolean doRestore = !update 10358 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 10359 10360 // Set up the post-install work request bookkeeping. This will be used 10361 // and cleaned up by the post-install event handling regardless of whether 10362 // there's a restore pass performed. Token values are >= 1. 10363 int token; 10364 if (mNextInstallToken < 0) mNextInstallToken = 1; 10365 token = mNextInstallToken++; 10366 10367 PostInstallData data = new PostInstallData(args, res); 10368 mRunningInstalls.put(token, data); 10369 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 10370 10371 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 10372 // Pass responsibility to the Backup Manager. It will perform a 10373 // restore if appropriate, then pass responsibility back to the 10374 // Package Manager to run the post-install observer callbacks 10375 // and broadcasts. 10376 IBackupManager bm = IBackupManager.Stub.asInterface( 10377 ServiceManager.getService(Context.BACKUP_SERVICE)); 10378 if (bm != null) { 10379 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 10380 + " to BM for possible restore"); 10381 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 10382 try { 10383 // TODO: http://b/22388012 10384 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 10385 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 10386 } else { 10387 doRestore = false; 10388 } 10389 } catch (RemoteException e) { 10390 // can't happen; the backup manager is local 10391 } catch (Exception e) { 10392 Slog.e(TAG, "Exception trying to enqueue restore", e); 10393 doRestore = false; 10394 } 10395 } else { 10396 Slog.e(TAG, "Backup Manager not found!"); 10397 doRestore = false; 10398 } 10399 } 10400 10401 if (!doRestore) { 10402 // No restore possible, or the Backup Manager was mysteriously not 10403 // available -- just fire the post-install work request directly. 10404 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 10405 10406 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 10407 10408 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 10409 mHandler.sendMessage(msg); 10410 } 10411 } 10412 }); 10413 } 10414 10415 private abstract class HandlerParams { 10416 private static final int MAX_RETRIES = 4; 10417 10418 /** 10419 * Number of times startCopy() has been attempted and had a non-fatal 10420 * error. 10421 */ 10422 private int mRetries = 0; 10423 10424 /** User handle for the user requesting the information or installation. */ 10425 private final UserHandle mUser; 10426 String traceMethod; 10427 int traceCookie; 10428 10429 HandlerParams(UserHandle user) { 10430 mUser = user; 10431 } 10432 10433 UserHandle getUser() { 10434 return mUser; 10435 } 10436 10437 HandlerParams setTraceMethod(String traceMethod) { 10438 this.traceMethod = traceMethod; 10439 return this; 10440 } 10441 10442 HandlerParams setTraceCookie(int traceCookie) { 10443 this.traceCookie = traceCookie; 10444 return this; 10445 } 10446 10447 final boolean startCopy() { 10448 boolean res; 10449 try { 10450 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 10451 10452 if (++mRetries > MAX_RETRIES) { 10453 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 10454 mHandler.sendEmptyMessage(MCS_GIVE_UP); 10455 handleServiceError(); 10456 return false; 10457 } else { 10458 handleStartCopy(); 10459 res = true; 10460 } 10461 } catch (RemoteException e) { 10462 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 10463 mHandler.sendEmptyMessage(MCS_RECONNECT); 10464 res = false; 10465 } 10466 handleReturnCode(); 10467 return res; 10468 } 10469 10470 final void serviceError() { 10471 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 10472 handleServiceError(); 10473 handleReturnCode(); 10474 } 10475 10476 abstract void handleStartCopy() throws RemoteException; 10477 abstract void handleServiceError(); 10478 abstract void handleReturnCode(); 10479 } 10480 10481 class MeasureParams extends HandlerParams { 10482 private final PackageStats mStats; 10483 private boolean mSuccess; 10484 10485 private final IPackageStatsObserver mObserver; 10486 10487 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 10488 super(new UserHandle(stats.userHandle)); 10489 mObserver = observer; 10490 mStats = stats; 10491 } 10492 10493 @Override 10494 public String toString() { 10495 return "MeasureParams{" 10496 + Integer.toHexString(System.identityHashCode(this)) 10497 + " " + mStats.packageName + "}"; 10498 } 10499 10500 @Override 10501 void handleStartCopy() throws RemoteException { 10502 synchronized (mInstallLock) { 10503 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 10504 } 10505 10506 if (mSuccess) { 10507 final boolean mounted; 10508 if (Environment.isExternalStorageEmulated()) { 10509 mounted = true; 10510 } else { 10511 final String status = Environment.getExternalStorageState(); 10512 mounted = (Environment.MEDIA_MOUNTED.equals(status) 10513 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 10514 } 10515 10516 if (mounted) { 10517 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 10518 10519 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 10520 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 10521 10522 mStats.externalDataSize = calculateDirectorySize(mContainerService, 10523 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 10524 10525 // Always subtract cache size, since it's a subdirectory 10526 mStats.externalDataSize -= mStats.externalCacheSize; 10527 10528 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 10529 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 10530 10531 mStats.externalObbSize = calculateDirectorySize(mContainerService, 10532 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 10533 } 10534 } 10535 } 10536 10537 @Override 10538 void handleReturnCode() { 10539 if (mObserver != null) { 10540 try { 10541 mObserver.onGetStatsCompleted(mStats, mSuccess); 10542 } catch (RemoteException e) { 10543 Slog.i(TAG, "Observer no longer exists."); 10544 } 10545 } 10546 } 10547 10548 @Override 10549 void handleServiceError() { 10550 Slog.e(TAG, "Could not measure application " + mStats.packageName 10551 + " external storage"); 10552 } 10553 } 10554 10555 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 10556 throws RemoteException { 10557 long result = 0; 10558 for (File path : paths) { 10559 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 10560 } 10561 return result; 10562 } 10563 10564 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 10565 for (File path : paths) { 10566 try { 10567 mcs.clearDirectory(path.getAbsolutePath()); 10568 } catch (RemoteException e) { 10569 } 10570 } 10571 } 10572 10573 static class OriginInfo { 10574 /** 10575 * Location where install is coming from, before it has been 10576 * copied/renamed into place. This could be a single monolithic APK 10577 * file, or a cluster directory. This location may be untrusted. 10578 */ 10579 final File file; 10580 final String cid; 10581 10582 /** 10583 * Flag indicating that {@link #file} or {@link #cid} has already been 10584 * staged, meaning downstream users don't need to defensively copy the 10585 * contents. 10586 */ 10587 final boolean staged; 10588 10589 /** 10590 * Flag indicating that {@link #file} or {@link #cid} is an already 10591 * installed app that is being moved. 10592 */ 10593 final boolean existing; 10594 10595 final String resolvedPath; 10596 final File resolvedFile; 10597 10598 static OriginInfo fromNothing() { 10599 return new OriginInfo(null, null, false, false); 10600 } 10601 10602 static OriginInfo fromUntrustedFile(File file) { 10603 return new OriginInfo(file, null, false, false); 10604 } 10605 10606 static OriginInfo fromExistingFile(File file) { 10607 return new OriginInfo(file, null, false, true); 10608 } 10609 10610 static OriginInfo fromStagedFile(File file) { 10611 return new OriginInfo(file, null, true, false); 10612 } 10613 10614 static OriginInfo fromStagedContainer(String cid) { 10615 return new OriginInfo(null, cid, true, false); 10616 } 10617 10618 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 10619 this.file = file; 10620 this.cid = cid; 10621 this.staged = staged; 10622 this.existing = existing; 10623 10624 if (cid != null) { 10625 resolvedPath = PackageHelper.getSdDir(cid); 10626 resolvedFile = new File(resolvedPath); 10627 } else if (file != null) { 10628 resolvedPath = file.getAbsolutePath(); 10629 resolvedFile = file; 10630 } else { 10631 resolvedPath = null; 10632 resolvedFile = null; 10633 } 10634 } 10635 } 10636 10637 class MoveInfo { 10638 final int moveId; 10639 final String fromUuid; 10640 final String toUuid; 10641 final String packageName; 10642 final String dataAppName; 10643 final int appId; 10644 final String seinfo; 10645 10646 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 10647 String dataAppName, int appId, String seinfo) { 10648 this.moveId = moveId; 10649 this.fromUuid = fromUuid; 10650 this.toUuid = toUuid; 10651 this.packageName = packageName; 10652 this.dataAppName = dataAppName; 10653 this.appId = appId; 10654 this.seinfo = seinfo; 10655 } 10656 } 10657 10658 class InstallParams extends HandlerParams { 10659 final OriginInfo origin; 10660 final MoveInfo move; 10661 final IPackageInstallObserver2 observer; 10662 int installFlags; 10663 final String installerPackageName; 10664 final String volumeUuid; 10665 final VerificationParams verificationParams; 10666 private InstallArgs mArgs; 10667 private int mRet; 10668 final String packageAbiOverride; 10669 final String[] grantedRuntimePermissions; 10670 10671 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 10672 int installFlags, String installerPackageName, String volumeUuid, 10673 VerificationParams verificationParams, UserHandle user, String packageAbiOverride, 10674 String[] grantedPermissions) { 10675 super(user); 10676 this.origin = origin; 10677 this.move = move; 10678 this.observer = observer; 10679 this.installFlags = installFlags; 10680 this.installerPackageName = installerPackageName; 10681 this.volumeUuid = volumeUuid; 10682 this.verificationParams = verificationParams; 10683 this.packageAbiOverride = packageAbiOverride; 10684 this.grantedRuntimePermissions = grantedPermissions; 10685 } 10686 10687 @Override 10688 public String toString() { 10689 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 10690 + " file=" + origin.file + " cid=" + origin.cid + "}"; 10691 } 10692 10693 public ManifestDigest getManifestDigest() { 10694 if (verificationParams == null) { 10695 return null; 10696 } 10697 return verificationParams.getManifestDigest(); 10698 } 10699 10700 private int installLocationPolicy(PackageInfoLite pkgLite) { 10701 String packageName = pkgLite.packageName; 10702 int installLocation = pkgLite.installLocation; 10703 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10704 // reader 10705 synchronized (mPackages) { 10706 PackageParser.Package pkg = mPackages.get(packageName); 10707 if (pkg != null) { 10708 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 10709 // Check for downgrading. 10710 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 10711 try { 10712 checkDowngrade(pkg, pkgLite); 10713 } catch (PackageManagerException e) { 10714 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 10715 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 10716 } 10717 } 10718 // Check for updated system application. 10719 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10720 if (onSd) { 10721 Slog.w(TAG, "Cannot install update to system app on sdcard"); 10722 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 10723 } 10724 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10725 } else { 10726 if (onSd) { 10727 // Install flag overrides everything. 10728 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10729 } 10730 // If current upgrade specifies particular preference 10731 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 10732 // Application explicitly specified internal. 10733 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10734 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 10735 // App explictly prefers external. Let policy decide 10736 } else { 10737 // Prefer previous location 10738 if (isExternal(pkg)) { 10739 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10740 } 10741 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10742 } 10743 } 10744 } else { 10745 // Invalid install. Return error code 10746 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 10747 } 10748 } 10749 } 10750 // All the special cases have been taken care of. 10751 // Return result based on recommended install location. 10752 if (onSd) { 10753 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10754 } 10755 return pkgLite.recommendedInstallLocation; 10756 } 10757 10758 /* 10759 * Invoke remote method to get package information and install 10760 * location values. Override install location based on default 10761 * policy if needed and then create install arguments based 10762 * on the install location. 10763 */ 10764 public void handleStartCopy() throws RemoteException { 10765 int ret = PackageManager.INSTALL_SUCCEEDED; 10766 10767 // If we're already staged, we've firmly committed to an install location 10768 if (origin.staged) { 10769 if (origin.file != null) { 10770 installFlags |= PackageManager.INSTALL_INTERNAL; 10771 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 10772 } else if (origin.cid != null) { 10773 installFlags |= PackageManager.INSTALL_EXTERNAL; 10774 installFlags &= ~PackageManager.INSTALL_INTERNAL; 10775 } else { 10776 throw new IllegalStateException("Invalid stage location"); 10777 } 10778 } 10779 10780 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10781 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 10782 PackageInfoLite pkgLite = null; 10783 10784 if (onInt && onSd) { 10785 // Check if both bits are set. 10786 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 10787 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 10788 } else { 10789 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 10790 packageAbiOverride); 10791 10792 /* 10793 * If we have too little free space, try to free cache 10794 * before giving up. 10795 */ 10796 if (!origin.staged && pkgLite.recommendedInstallLocation 10797 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 10798 // TODO: focus freeing disk space on the target device 10799 final StorageManager storage = StorageManager.from(mContext); 10800 final long lowThreshold = storage.getStorageLowBytes( 10801 Environment.getDataDirectory()); 10802 10803 final long sizeBytes = mContainerService.calculateInstalledSize( 10804 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 10805 10806 if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) { 10807 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 10808 installFlags, packageAbiOverride); 10809 } 10810 10811 /* 10812 * The cache free must have deleted the file we 10813 * downloaded to install. 10814 * 10815 * TODO: fix the "freeCache" call to not delete 10816 * the file we care about. 10817 */ 10818 if (pkgLite.recommendedInstallLocation 10819 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 10820 pkgLite.recommendedInstallLocation 10821 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 10822 } 10823 } 10824 } 10825 10826 if (ret == PackageManager.INSTALL_SUCCEEDED) { 10827 int loc = pkgLite.recommendedInstallLocation; 10828 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 10829 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 10830 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 10831 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 10832 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 10833 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10834 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 10835 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 10836 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 10837 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 10838 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 10839 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 10840 } else { 10841 // Override with defaults if needed. 10842 loc = installLocationPolicy(pkgLite); 10843 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 10844 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 10845 } else if (!onSd && !onInt) { 10846 // Override install location with flags 10847 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 10848 // Set the flag to install on external media. 10849 installFlags |= PackageManager.INSTALL_EXTERNAL; 10850 installFlags &= ~PackageManager.INSTALL_INTERNAL; 10851 } else { 10852 // Make sure the flag for installing on external 10853 // media is unset 10854 installFlags |= PackageManager.INSTALL_INTERNAL; 10855 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 10856 } 10857 } 10858 } 10859 } 10860 10861 final InstallArgs args = createInstallArgs(this); 10862 mArgs = args; 10863 10864 if (ret == PackageManager.INSTALL_SUCCEEDED) { 10865 // TODO: http://b/22976637 10866 // Apps installed for "all" users use the device owner to verify the app 10867 UserHandle verifierUser = getUser(); 10868 if (verifierUser == UserHandle.ALL) { 10869 verifierUser = UserHandle.SYSTEM; 10870 } 10871 10872 /* 10873 * Determine if we have any installed package verifiers. If we 10874 * do, then we'll defer to them to verify the packages. 10875 */ 10876 final int requiredUid = mRequiredVerifierPackage == null ? -1 10877 : getPackageUid(mRequiredVerifierPackage, verifierUser.getIdentifier()); 10878 if (!origin.existing && requiredUid != -1 10879 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 10880 final Intent verification = new Intent( 10881 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 10882 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10883 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 10884 PACKAGE_MIME_TYPE); 10885 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10886 10887 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 10888 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 10889 verifierUser.getIdentifier()); 10890 10891 if (DEBUG_VERIFY) { 10892 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 10893 + verification.toString() + " with " + pkgLite.verifiers.length 10894 + " optional verifiers"); 10895 } 10896 10897 final int verificationId = mPendingVerificationToken++; 10898 10899 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10900 10901 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 10902 installerPackageName); 10903 10904 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 10905 installFlags); 10906 10907 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 10908 pkgLite.packageName); 10909 10910 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 10911 pkgLite.versionCode); 10912 10913 if (verificationParams != null) { 10914 if (verificationParams.getVerificationURI() != null) { 10915 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 10916 verificationParams.getVerificationURI()); 10917 } 10918 if (verificationParams.getOriginatingURI() != null) { 10919 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 10920 verificationParams.getOriginatingURI()); 10921 } 10922 if (verificationParams.getReferrer() != null) { 10923 verification.putExtra(Intent.EXTRA_REFERRER, 10924 verificationParams.getReferrer()); 10925 } 10926 if (verificationParams.getOriginatingUid() >= 0) { 10927 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 10928 verificationParams.getOriginatingUid()); 10929 } 10930 if (verificationParams.getInstallerUid() >= 0) { 10931 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 10932 verificationParams.getInstallerUid()); 10933 } 10934 } 10935 10936 final PackageVerificationState verificationState = new PackageVerificationState( 10937 requiredUid, args); 10938 10939 mPendingVerification.append(verificationId, verificationState); 10940 10941 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 10942 receivers, verificationState); 10943 10944 /* 10945 * If any sufficient verifiers were listed in the package 10946 * manifest, attempt to ask them. 10947 */ 10948 if (sufficientVerifiers != null) { 10949 final int N = sufficientVerifiers.size(); 10950 if (N == 0) { 10951 Slog.i(TAG, "Additional verifiers required, but none installed."); 10952 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 10953 } else { 10954 for (int i = 0; i < N; i++) { 10955 final ComponentName verifierComponent = sufficientVerifiers.get(i); 10956 10957 final Intent sufficientIntent = new Intent(verification); 10958 sufficientIntent.setComponent(verifierComponent); 10959 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 10960 } 10961 } 10962 } 10963 10964 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 10965 mRequiredVerifierPackage, receivers); 10966 if (ret == PackageManager.INSTALL_SUCCEEDED 10967 && mRequiredVerifierPackage != null) { 10968 Trace.asyncTraceBegin( 10969 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 10970 /* 10971 * Send the intent to the required verification agent, 10972 * but only start the verification timeout after the 10973 * target BroadcastReceivers have run. 10974 */ 10975 verification.setComponent(requiredVerifierComponent); 10976 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 10977 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10978 new BroadcastReceiver() { 10979 @Override 10980 public void onReceive(Context context, Intent intent) { 10981 final Message msg = mHandler 10982 .obtainMessage(CHECK_PENDING_VERIFICATION); 10983 msg.arg1 = verificationId; 10984 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 10985 } 10986 }, null, 0, null, null); 10987 10988 /* 10989 * We don't want the copy to proceed until verification 10990 * succeeds, so null out this field. 10991 */ 10992 mArgs = null; 10993 } 10994 } else { 10995 /* 10996 * No package verification is enabled, so immediately start 10997 * the remote call to initiate copy using temporary file. 10998 */ 10999 ret = args.copyApk(mContainerService, true); 11000 } 11001 } 11002 11003 mRet = ret; 11004 } 11005 11006 @Override 11007 void handleReturnCode() { 11008 // If mArgs is null, then MCS couldn't be reached. When it 11009 // reconnects, it will try again to install. At that point, this 11010 // will succeed. 11011 if (mArgs != null) { 11012 processPendingInstall(mArgs, mRet); 11013 } 11014 } 11015 11016 @Override 11017 void handleServiceError() { 11018 mArgs = createInstallArgs(this); 11019 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11020 } 11021 11022 public boolean isForwardLocked() { 11023 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11024 } 11025 } 11026 11027 /** 11028 * Used during creation of InstallArgs 11029 * 11030 * @param installFlags package installation flags 11031 * @return true if should be installed on external storage 11032 */ 11033 private static boolean installOnExternalAsec(int installFlags) { 11034 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 11035 return false; 11036 } 11037 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 11038 return true; 11039 } 11040 return false; 11041 } 11042 11043 /** 11044 * Used during creation of InstallArgs 11045 * 11046 * @param installFlags package installation flags 11047 * @return true if should be installed as forward locked 11048 */ 11049 private static boolean installForwardLocked(int installFlags) { 11050 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11051 } 11052 11053 private InstallArgs createInstallArgs(InstallParams params) { 11054 if (params.move != null) { 11055 return new MoveInstallArgs(params); 11056 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 11057 return new AsecInstallArgs(params); 11058 } else { 11059 return new FileInstallArgs(params); 11060 } 11061 } 11062 11063 /** 11064 * Create args that describe an existing installed package. Typically used 11065 * when cleaning up old installs, or used as a move source. 11066 */ 11067 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 11068 String resourcePath, String[] instructionSets) { 11069 final boolean isInAsec; 11070 if (installOnExternalAsec(installFlags)) { 11071 /* Apps on SD card are always in ASEC containers. */ 11072 isInAsec = true; 11073 } else if (installForwardLocked(installFlags) 11074 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 11075 /* 11076 * Forward-locked apps are only in ASEC containers if they're the 11077 * new style 11078 */ 11079 isInAsec = true; 11080 } else { 11081 isInAsec = false; 11082 } 11083 11084 if (isInAsec) { 11085 return new AsecInstallArgs(codePath, instructionSets, 11086 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 11087 } else { 11088 return new FileInstallArgs(codePath, resourcePath, instructionSets); 11089 } 11090 } 11091 11092 static abstract class InstallArgs { 11093 /** @see InstallParams#origin */ 11094 final OriginInfo origin; 11095 /** @see InstallParams#move */ 11096 final MoveInfo move; 11097 11098 final IPackageInstallObserver2 observer; 11099 // Always refers to PackageManager flags only 11100 final int installFlags; 11101 final String installerPackageName; 11102 final String volumeUuid; 11103 final ManifestDigest manifestDigest; 11104 final UserHandle user; 11105 final String abiOverride; 11106 final String[] installGrantPermissions; 11107 /** If non-null, drop an async trace when the install completes */ 11108 final String traceMethod; 11109 final int traceCookie; 11110 11111 // The list of instruction sets supported by this app. This is currently 11112 // only used during the rmdex() phase to clean up resources. We can get rid of this 11113 // if we move dex files under the common app path. 11114 /* nullable */ String[] instructionSets; 11115 11116 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 11117 int installFlags, String installerPackageName, String volumeUuid, 11118 ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, 11119 String abiOverride, String[] installGrantPermissions, 11120 String traceMethod, int traceCookie) { 11121 this.origin = origin; 11122 this.move = move; 11123 this.installFlags = installFlags; 11124 this.observer = observer; 11125 this.installerPackageName = installerPackageName; 11126 this.volumeUuid = volumeUuid; 11127 this.manifestDigest = manifestDigest; 11128 this.user = user; 11129 this.instructionSets = instructionSets; 11130 this.abiOverride = abiOverride; 11131 this.installGrantPermissions = installGrantPermissions; 11132 this.traceMethod = traceMethod; 11133 this.traceCookie = traceCookie; 11134 } 11135 11136 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 11137 abstract int doPreInstall(int status); 11138 11139 /** 11140 * Rename package into final resting place. All paths on the given 11141 * scanned package should be updated to reflect the rename. 11142 */ 11143 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 11144 abstract int doPostInstall(int status, int uid); 11145 11146 /** @see PackageSettingBase#codePathString */ 11147 abstract String getCodePath(); 11148 /** @see PackageSettingBase#resourcePathString */ 11149 abstract String getResourcePath(); 11150 11151 // Need installer lock especially for dex file removal. 11152 abstract void cleanUpResourcesLI(); 11153 abstract boolean doPostDeleteLI(boolean delete); 11154 11155 /** 11156 * Called before the source arguments are copied. This is used mostly 11157 * for MoveParams when it needs to read the source file to put it in the 11158 * destination. 11159 */ 11160 int doPreCopy() { 11161 return PackageManager.INSTALL_SUCCEEDED; 11162 } 11163 11164 /** 11165 * Called after the source arguments are copied. This is used mostly for 11166 * MoveParams when it needs to read the source file to put it in the 11167 * destination. 11168 * 11169 * @return 11170 */ 11171 int doPostCopy(int uid) { 11172 return PackageManager.INSTALL_SUCCEEDED; 11173 } 11174 11175 protected boolean isFwdLocked() { 11176 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11177 } 11178 11179 protected boolean isExternalAsec() { 11180 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11181 } 11182 11183 UserHandle getUser() { 11184 return user; 11185 } 11186 } 11187 11188 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 11189 if (!allCodePaths.isEmpty()) { 11190 if (instructionSets == null) { 11191 throw new IllegalStateException("instructionSet == null"); 11192 } 11193 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 11194 for (String codePath : allCodePaths) { 11195 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 11196 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 11197 if (retCode < 0) { 11198 Slog.w(TAG, "Couldn't remove dex file for package: " 11199 + " at location " + codePath + ", retcode=" + retCode); 11200 // we don't consider this to be a failure of the core package deletion 11201 } 11202 } 11203 } 11204 } 11205 } 11206 11207 /** 11208 * Logic to handle installation of non-ASEC applications, including copying 11209 * and renaming logic. 11210 */ 11211 class FileInstallArgs extends InstallArgs { 11212 private File codeFile; 11213 private File resourceFile; 11214 11215 // Example topology: 11216 // /data/app/com.example/base.apk 11217 // /data/app/com.example/split_foo.apk 11218 // /data/app/com.example/lib/arm/libfoo.so 11219 // /data/app/com.example/lib/arm64/libfoo.so 11220 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 11221 11222 /** New install */ 11223 FileInstallArgs(InstallParams params) { 11224 super(params.origin, params.move, params.observer, params.installFlags, 11225 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11226 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11227 params.grantedRuntimePermissions, 11228 params.traceMethod, params.traceCookie); 11229 if (isFwdLocked()) { 11230 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 11231 } 11232 } 11233 11234 /** Existing install */ 11235 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 11236 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets, 11237 null, null, null, 0); 11238 this.codeFile = (codePath != null) ? new File(codePath) : null; 11239 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 11240 } 11241 11242 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11243 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 11244 try { 11245 return doCopyApk(imcs, temp); 11246 } finally { 11247 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 11248 } 11249 } 11250 11251 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11252 if (origin.staged) { 11253 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 11254 codeFile = origin.file; 11255 resourceFile = origin.file; 11256 return PackageManager.INSTALL_SUCCEEDED; 11257 } 11258 11259 try { 11260 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid); 11261 codeFile = tempDir; 11262 resourceFile = tempDir; 11263 } catch (IOException e) { 11264 Slog.w(TAG, "Failed to create copy file: " + e); 11265 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11266 } 11267 11268 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 11269 @Override 11270 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 11271 if (!FileUtils.isValidExtFilename(name)) { 11272 throw new IllegalArgumentException("Invalid filename: " + name); 11273 } 11274 try { 11275 final File file = new File(codeFile, name); 11276 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 11277 O_RDWR | O_CREAT, 0644); 11278 Os.chmod(file.getAbsolutePath(), 0644); 11279 return new ParcelFileDescriptor(fd); 11280 } catch (ErrnoException e) { 11281 throw new RemoteException("Failed to open: " + e.getMessage()); 11282 } 11283 } 11284 }; 11285 11286 int ret = PackageManager.INSTALL_SUCCEEDED; 11287 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 11288 if (ret != PackageManager.INSTALL_SUCCEEDED) { 11289 Slog.e(TAG, "Failed to copy package"); 11290 return ret; 11291 } 11292 11293 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 11294 NativeLibraryHelper.Handle handle = null; 11295 try { 11296 handle = NativeLibraryHelper.Handle.create(codeFile); 11297 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 11298 abiOverride); 11299 } catch (IOException e) { 11300 Slog.e(TAG, "Copying native libraries failed", e); 11301 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11302 } finally { 11303 IoUtils.closeQuietly(handle); 11304 } 11305 11306 return ret; 11307 } 11308 11309 int doPreInstall(int status) { 11310 if (status != PackageManager.INSTALL_SUCCEEDED) { 11311 cleanUp(); 11312 } 11313 return status; 11314 } 11315 11316 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11317 if (status != PackageManager.INSTALL_SUCCEEDED) { 11318 cleanUp(); 11319 return false; 11320 } 11321 11322 final File targetDir = codeFile.getParentFile(); 11323 final File beforeCodeFile = codeFile; 11324 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 11325 11326 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 11327 try { 11328 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 11329 } catch (ErrnoException e) { 11330 Slog.w(TAG, "Failed to rename", e); 11331 return false; 11332 } 11333 11334 if (!SELinux.restoreconRecursive(afterCodeFile)) { 11335 Slog.w(TAG, "Failed to restorecon"); 11336 return false; 11337 } 11338 11339 // Reflect the rename internally 11340 codeFile = afterCodeFile; 11341 resourceFile = afterCodeFile; 11342 11343 // Reflect the rename in scanned details 11344 pkg.codePath = afterCodeFile.getAbsolutePath(); 11345 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11346 pkg.baseCodePath); 11347 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11348 pkg.splitCodePaths); 11349 11350 // Reflect the rename in app info 11351 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11352 pkg.applicationInfo.setCodePath(pkg.codePath); 11353 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11354 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11355 pkg.applicationInfo.setResourcePath(pkg.codePath); 11356 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11357 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11358 11359 return true; 11360 } 11361 11362 int doPostInstall(int status, int uid) { 11363 if (status != PackageManager.INSTALL_SUCCEEDED) { 11364 cleanUp(); 11365 } 11366 return status; 11367 } 11368 11369 @Override 11370 String getCodePath() { 11371 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 11372 } 11373 11374 @Override 11375 String getResourcePath() { 11376 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 11377 } 11378 11379 private boolean cleanUp() { 11380 if (codeFile == null || !codeFile.exists()) { 11381 return false; 11382 } 11383 11384 if (codeFile.isDirectory()) { 11385 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 11386 } else { 11387 codeFile.delete(); 11388 } 11389 11390 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 11391 resourceFile.delete(); 11392 } 11393 11394 return true; 11395 } 11396 11397 void cleanUpResourcesLI() { 11398 // Try enumerating all code paths before deleting 11399 List<String> allCodePaths = Collections.EMPTY_LIST; 11400 if (codeFile != null && codeFile.exists()) { 11401 try { 11402 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 11403 allCodePaths = pkg.getAllCodePaths(); 11404 } catch (PackageParserException e) { 11405 // Ignored; we tried our best 11406 } 11407 } 11408 11409 cleanUp(); 11410 removeDexFiles(allCodePaths, instructionSets); 11411 } 11412 11413 boolean doPostDeleteLI(boolean delete) { 11414 // XXX err, shouldn't we respect the delete flag? 11415 cleanUpResourcesLI(); 11416 return true; 11417 } 11418 } 11419 11420 private boolean isAsecExternal(String cid) { 11421 final String asecPath = PackageHelper.getSdFilesystem(cid); 11422 return !asecPath.startsWith(mAsecInternalPath); 11423 } 11424 11425 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 11426 PackageManagerException { 11427 if (copyRet < 0) { 11428 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 11429 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 11430 throw new PackageManagerException(copyRet, message); 11431 } 11432 } 11433 } 11434 11435 /** 11436 * Extract the MountService "container ID" from the full code path of an 11437 * .apk. 11438 */ 11439 static String cidFromCodePath(String fullCodePath) { 11440 int eidx = fullCodePath.lastIndexOf("/"); 11441 String subStr1 = fullCodePath.substring(0, eidx); 11442 int sidx = subStr1.lastIndexOf("/"); 11443 return subStr1.substring(sidx+1, eidx); 11444 } 11445 11446 /** 11447 * Logic to handle installation of ASEC applications, including copying and 11448 * renaming logic. 11449 */ 11450 class AsecInstallArgs extends InstallArgs { 11451 static final String RES_FILE_NAME = "pkg.apk"; 11452 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 11453 11454 String cid; 11455 String packagePath; 11456 String resourcePath; 11457 11458 /** New install */ 11459 AsecInstallArgs(InstallParams params) { 11460 super(params.origin, params.move, params.observer, params.installFlags, 11461 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11462 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11463 params.grantedRuntimePermissions, 11464 params.traceMethod, params.traceCookie); 11465 } 11466 11467 /** Existing install */ 11468 AsecInstallArgs(String fullCodePath, String[] instructionSets, 11469 boolean isExternal, boolean isForwardLocked) { 11470 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 11471 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 11472 instructionSets, null, null, null, 0); 11473 // Hackily pretend we're still looking at a full code path 11474 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 11475 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 11476 } 11477 11478 // Extract cid from fullCodePath 11479 int eidx = fullCodePath.lastIndexOf("/"); 11480 String subStr1 = fullCodePath.substring(0, eidx); 11481 int sidx = subStr1.lastIndexOf("/"); 11482 cid = subStr1.substring(sidx+1, eidx); 11483 setMountPath(subStr1); 11484 } 11485 11486 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 11487 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 11488 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 11489 instructionSets, null, null, null, 0); 11490 this.cid = cid; 11491 setMountPath(PackageHelper.getSdDir(cid)); 11492 } 11493 11494 void createCopyFile() { 11495 cid = mInstallerService.allocateExternalStageCidLegacy(); 11496 } 11497 11498 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11499 if (origin.staged) { 11500 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 11501 cid = origin.cid; 11502 setMountPath(PackageHelper.getSdDir(cid)); 11503 return PackageManager.INSTALL_SUCCEEDED; 11504 } 11505 11506 if (temp) { 11507 createCopyFile(); 11508 } else { 11509 /* 11510 * Pre-emptively destroy the container since it's destroyed if 11511 * copying fails due to it existing anyway. 11512 */ 11513 PackageHelper.destroySdDir(cid); 11514 } 11515 11516 final String newMountPath = imcs.copyPackageToContainer( 11517 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 11518 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 11519 11520 if (newMountPath != null) { 11521 setMountPath(newMountPath); 11522 return PackageManager.INSTALL_SUCCEEDED; 11523 } else { 11524 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11525 } 11526 } 11527 11528 @Override 11529 String getCodePath() { 11530 return packagePath; 11531 } 11532 11533 @Override 11534 String getResourcePath() { 11535 return resourcePath; 11536 } 11537 11538 int doPreInstall(int status) { 11539 if (status != PackageManager.INSTALL_SUCCEEDED) { 11540 // Destroy container 11541 PackageHelper.destroySdDir(cid); 11542 } else { 11543 boolean mounted = PackageHelper.isContainerMounted(cid); 11544 if (!mounted) { 11545 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 11546 Process.SYSTEM_UID); 11547 if (newMountPath != null) { 11548 setMountPath(newMountPath); 11549 } else { 11550 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11551 } 11552 } 11553 } 11554 return status; 11555 } 11556 11557 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11558 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 11559 String newMountPath = null; 11560 if (PackageHelper.isContainerMounted(cid)) { 11561 // Unmount the container 11562 if (!PackageHelper.unMountSdDir(cid)) { 11563 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 11564 return false; 11565 } 11566 } 11567 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 11568 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 11569 " which might be stale. Will try to clean up."); 11570 // Clean up the stale container and proceed to recreate. 11571 if (!PackageHelper.destroySdDir(newCacheId)) { 11572 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 11573 return false; 11574 } 11575 // Successfully cleaned up stale container. Try to rename again. 11576 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 11577 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 11578 + " inspite of cleaning it up."); 11579 return false; 11580 } 11581 } 11582 if (!PackageHelper.isContainerMounted(newCacheId)) { 11583 Slog.w(TAG, "Mounting container " + newCacheId); 11584 newMountPath = PackageHelper.mountSdDir(newCacheId, 11585 getEncryptKey(), Process.SYSTEM_UID); 11586 } else { 11587 newMountPath = PackageHelper.getSdDir(newCacheId); 11588 } 11589 if (newMountPath == null) { 11590 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 11591 return false; 11592 } 11593 Log.i(TAG, "Succesfully renamed " + cid + 11594 " to " + newCacheId + 11595 " at new path: " + newMountPath); 11596 cid = newCacheId; 11597 11598 final File beforeCodeFile = new File(packagePath); 11599 setMountPath(newMountPath); 11600 final File afterCodeFile = new File(packagePath); 11601 11602 // Reflect the rename in scanned details 11603 pkg.codePath = afterCodeFile.getAbsolutePath(); 11604 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11605 pkg.baseCodePath); 11606 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11607 pkg.splitCodePaths); 11608 11609 // Reflect the rename in app info 11610 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11611 pkg.applicationInfo.setCodePath(pkg.codePath); 11612 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11613 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11614 pkg.applicationInfo.setResourcePath(pkg.codePath); 11615 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11616 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11617 11618 return true; 11619 } 11620 11621 private void setMountPath(String mountPath) { 11622 final File mountFile = new File(mountPath); 11623 11624 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 11625 if (monolithicFile.exists()) { 11626 packagePath = monolithicFile.getAbsolutePath(); 11627 if (isFwdLocked()) { 11628 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 11629 } else { 11630 resourcePath = packagePath; 11631 } 11632 } else { 11633 packagePath = mountFile.getAbsolutePath(); 11634 resourcePath = packagePath; 11635 } 11636 } 11637 11638 int doPostInstall(int status, int uid) { 11639 if (status != PackageManager.INSTALL_SUCCEEDED) { 11640 cleanUp(); 11641 } else { 11642 final int groupOwner; 11643 final String protectedFile; 11644 if (isFwdLocked()) { 11645 groupOwner = UserHandle.getSharedAppGid(uid); 11646 protectedFile = RES_FILE_NAME; 11647 } else { 11648 groupOwner = -1; 11649 protectedFile = null; 11650 } 11651 11652 if (uid < Process.FIRST_APPLICATION_UID 11653 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 11654 Slog.e(TAG, "Failed to finalize " + cid); 11655 PackageHelper.destroySdDir(cid); 11656 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11657 } 11658 11659 boolean mounted = PackageHelper.isContainerMounted(cid); 11660 if (!mounted) { 11661 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 11662 } 11663 } 11664 return status; 11665 } 11666 11667 private void cleanUp() { 11668 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 11669 11670 // Destroy secure container 11671 PackageHelper.destroySdDir(cid); 11672 } 11673 11674 private List<String> getAllCodePaths() { 11675 final File codeFile = new File(getCodePath()); 11676 if (codeFile != null && codeFile.exists()) { 11677 try { 11678 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 11679 return pkg.getAllCodePaths(); 11680 } catch (PackageParserException e) { 11681 // Ignored; we tried our best 11682 } 11683 } 11684 return Collections.EMPTY_LIST; 11685 } 11686 11687 void cleanUpResourcesLI() { 11688 // Enumerate all code paths before deleting 11689 cleanUpResourcesLI(getAllCodePaths()); 11690 } 11691 11692 private void cleanUpResourcesLI(List<String> allCodePaths) { 11693 cleanUp(); 11694 removeDexFiles(allCodePaths, instructionSets); 11695 } 11696 11697 String getPackageName() { 11698 return getAsecPackageName(cid); 11699 } 11700 11701 boolean doPostDeleteLI(boolean delete) { 11702 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 11703 final List<String> allCodePaths = getAllCodePaths(); 11704 boolean mounted = PackageHelper.isContainerMounted(cid); 11705 if (mounted) { 11706 // Unmount first 11707 if (PackageHelper.unMountSdDir(cid)) { 11708 mounted = false; 11709 } 11710 } 11711 if (!mounted && delete) { 11712 cleanUpResourcesLI(allCodePaths); 11713 } 11714 return !mounted; 11715 } 11716 11717 @Override 11718 int doPreCopy() { 11719 if (isFwdLocked()) { 11720 if (!PackageHelper.fixSdPermissions(cid, 11721 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 11722 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11723 } 11724 } 11725 11726 return PackageManager.INSTALL_SUCCEEDED; 11727 } 11728 11729 @Override 11730 int doPostCopy(int uid) { 11731 if (isFwdLocked()) { 11732 if (uid < Process.FIRST_APPLICATION_UID 11733 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 11734 RES_FILE_NAME)) { 11735 Slog.e(TAG, "Failed to finalize " + cid); 11736 PackageHelper.destroySdDir(cid); 11737 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11738 } 11739 } 11740 11741 return PackageManager.INSTALL_SUCCEEDED; 11742 } 11743 } 11744 11745 /** 11746 * Logic to handle movement of existing installed applications. 11747 */ 11748 class MoveInstallArgs extends InstallArgs { 11749 private File codeFile; 11750 private File resourceFile; 11751 11752 /** New install */ 11753 MoveInstallArgs(InstallParams params) { 11754 super(params.origin, params.move, params.observer, params.installFlags, 11755 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11756 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11757 params.grantedRuntimePermissions, 11758 params.traceMethod, params.traceCookie); 11759 } 11760 11761 int copyApk(IMediaContainerService imcs, boolean temp) { 11762 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 11763 + move.fromUuid + " to " + move.toUuid); 11764 synchronized (mInstaller) { 11765 if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName, 11766 move.dataAppName, move.appId, move.seinfo) != 0) { 11767 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11768 } 11769 } 11770 11771 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 11772 resourceFile = codeFile; 11773 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 11774 11775 return PackageManager.INSTALL_SUCCEEDED; 11776 } 11777 11778 int doPreInstall(int status) { 11779 if (status != PackageManager.INSTALL_SUCCEEDED) { 11780 cleanUp(move.toUuid); 11781 } 11782 return status; 11783 } 11784 11785 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11786 if (status != PackageManager.INSTALL_SUCCEEDED) { 11787 cleanUp(move.toUuid); 11788 return false; 11789 } 11790 11791 // Reflect the move in app info 11792 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11793 pkg.applicationInfo.setCodePath(pkg.codePath); 11794 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11795 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11796 pkg.applicationInfo.setResourcePath(pkg.codePath); 11797 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11798 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11799 11800 return true; 11801 } 11802 11803 int doPostInstall(int status, int uid) { 11804 if (status == PackageManager.INSTALL_SUCCEEDED) { 11805 cleanUp(move.fromUuid); 11806 } else { 11807 cleanUp(move.toUuid); 11808 } 11809 return status; 11810 } 11811 11812 @Override 11813 String getCodePath() { 11814 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 11815 } 11816 11817 @Override 11818 String getResourcePath() { 11819 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 11820 } 11821 11822 private boolean cleanUp(String volumeUuid) { 11823 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 11824 move.dataAppName); 11825 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 11826 synchronized (mInstallLock) { 11827 // Clean up both app data and code 11828 removeDataDirsLI(volumeUuid, move.packageName); 11829 if (codeFile.isDirectory()) { 11830 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 11831 } else { 11832 codeFile.delete(); 11833 } 11834 } 11835 return true; 11836 } 11837 11838 void cleanUpResourcesLI() { 11839 throw new UnsupportedOperationException(); 11840 } 11841 11842 boolean doPostDeleteLI(boolean delete) { 11843 throw new UnsupportedOperationException(); 11844 } 11845 } 11846 11847 static String getAsecPackageName(String packageCid) { 11848 int idx = packageCid.lastIndexOf("-"); 11849 if (idx == -1) { 11850 return packageCid; 11851 } 11852 return packageCid.substring(0, idx); 11853 } 11854 11855 // Utility method used to create code paths based on package name and available index. 11856 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 11857 String idxStr = ""; 11858 int idx = 1; 11859 // Fall back to default value of idx=1 if prefix is not 11860 // part of oldCodePath 11861 if (oldCodePath != null) { 11862 String subStr = oldCodePath; 11863 // Drop the suffix right away 11864 if (suffix != null && subStr.endsWith(suffix)) { 11865 subStr = subStr.substring(0, subStr.length() - suffix.length()); 11866 } 11867 // If oldCodePath already contains prefix find out the 11868 // ending index to either increment or decrement. 11869 int sidx = subStr.lastIndexOf(prefix); 11870 if (sidx != -1) { 11871 subStr = subStr.substring(sidx + prefix.length()); 11872 if (subStr != null) { 11873 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 11874 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 11875 } 11876 try { 11877 idx = Integer.parseInt(subStr); 11878 if (idx <= 1) { 11879 idx++; 11880 } else { 11881 idx--; 11882 } 11883 } catch(NumberFormatException e) { 11884 } 11885 } 11886 } 11887 } 11888 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 11889 return prefix + idxStr; 11890 } 11891 11892 private File getNextCodePath(File targetDir, String packageName) { 11893 int suffix = 1; 11894 File result; 11895 do { 11896 result = new File(targetDir, packageName + "-" + suffix); 11897 suffix++; 11898 } while (result.exists()); 11899 return result; 11900 } 11901 11902 // Utility method that returns the relative package path with respect 11903 // to the installation directory. Like say for /data/data/com.test-1.apk 11904 // string com.test-1 is returned. 11905 static String deriveCodePathName(String codePath) { 11906 if (codePath == null) { 11907 return null; 11908 } 11909 final File codeFile = new File(codePath); 11910 final String name = codeFile.getName(); 11911 if (codeFile.isDirectory()) { 11912 return name; 11913 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 11914 final int lastDot = name.lastIndexOf('.'); 11915 return name.substring(0, lastDot); 11916 } else { 11917 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 11918 return null; 11919 } 11920 } 11921 11922 class PackageInstalledInfo { 11923 String name; 11924 int uid; 11925 // The set of users that originally had this package installed. 11926 int[] origUsers; 11927 // The set of users that now have this package installed. 11928 int[] newUsers; 11929 PackageParser.Package pkg; 11930 int returnCode; 11931 String returnMsg; 11932 PackageRemovedInfo removedInfo; 11933 11934 public void setError(int code, String msg) { 11935 returnCode = code; 11936 returnMsg = msg; 11937 Slog.w(TAG, msg); 11938 } 11939 11940 public void setError(String msg, PackageParserException e) { 11941 returnCode = e.error; 11942 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11943 Slog.w(TAG, msg, e); 11944 } 11945 11946 public void setError(String msg, PackageManagerException e) { 11947 returnCode = e.error; 11948 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11949 Slog.w(TAG, msg, e); 11950 } 11951 11952 // In some error cases we want to convey more info back to the observer 11953 String origPackage; 11954 String origPermission; 11955 } 11956 11957 /* 11958 * Install a non-existing package. 11959 */ 11960 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 11961 UserHandle user, String installerPackageName, String volumeUuid, 11962 PackageInstalledInfo res) { 11963 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 11964 11965 // Remember this for later, in case we need to rollback this install 11966 String pkgName = pkg.packageName; 11967 11968 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 11969 // TODO: b/23350563 11970 final boolean dataDirExists = Environment 11971 .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_SYSTEM, pkgName).exists(); 11972 11973 synchronized(mPackages) { 11974 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 11975 // A package with the same name is already installed, though 11976 // it has been renamed to an older name. The package we 11977 // are trying to install should be installed as an update to 11978 // the existing one, but that has not been requested, so bail. 11979 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 11980 + " without first uninstalling package running as " 11981 + mSettings.mRenamedPackages.get(pkgName)); 11982 return; 11983 } 11984 if (mPackages.containsKey(pkgName)) { 11985 // Don't allow installation over an existing package with the same name. 11986 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 11987 + " without first uninstalling."); 11988 return; 11989 } 11990 } 11991 11992 try { 11993 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 11994 System.currentTimeMillis(), user); 11995 11996 updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user); 11997 // delete the partially installed application. the data directory will have to be 11998 // restored if it was already existing 11999 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12000 // remove package from internal structures. Note that we want deletePackageX to 12001 // delete the package data and cache directories that it created in 12002 // scanPackageLocked, unless those directories existed before we even tried to 12003 // install. 12004 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 12005 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 12006 res.removedInfo, true); 12007 } 12008 12009 } catch (PackageManagerException e) { 12010 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12011 } 12012 12013 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12014 } 12015 12016 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 12017 // Can't rotate keys during boot or if sharedUser. 12018 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 12019 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 12020 return false; 12021 } 12022 // app is using upgradeKeySets; make sure all are valid 12023 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12024 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 12025 for (int i = 0; i < upgradeKeySets.length; i++) { 12026 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 12027 Slog.wtf(TAG, "Package " 12028 + (oldPs.name != null ? oldPs.name : "<null>") 12029 + " contains upgrade-key-set reference to unknown key-set: " 12030 + upgradeKeySets[i] 12031 + " reverting to signatures check."); 12032 return false; 12033 } 12034 } 12035 return true; 12036 } 12037 12038 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 12039 // Upgrade keysets are being used. Determine if new package has a superset of the 12040 // required keys. 12041 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 12042 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12043 for (int i = 0; i < upgradeKeySets.length; i++) { 12044 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 12045 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 12046 return true; 12047 } 12048 } 12049 return false; 12050 } 12051 12052 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 12053 UserHandle user, String installerPackageName, String volumeUuid, 12054 PackageInstalledInfo res) { 12055 final PackageParser.Package oldPackage; 12056 final String pkgName = pkg.packageName; 12057 final int[] allUsers; 12058 final boolean[] perUserInstalled; 12059 12060 // First find the old package info and check signatures 12061 synchronized(mPackages) { 12062 oldPackage = mPackages.get(pkgName); 12063 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 12064 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12065 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 12066 if(!checkUpgradeKeySetLP(ps, pkg)) { 12067 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 12068 "New package not signed by keys specified by upgrade-keysets: " 12069 + pkgName); 12070 return; 12071 } 12072 } else { 12073 // default to original signature matching 12074 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 12075 != PackageManager.SIGNATURE_MATCH) { 12076 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 12077 "New package has a different signature: " + pkgName); 12078 return; 12079 } 12080 } 12081 12082 // In case of rollback, remember per-user/profile install state 12083 allUsers = sUserManager.getUserIds(); 12084 perUserInstalled = new boolean[allUsers.length]; 12085 for (int i = 0; i < allUsers.length; i++) { 12086 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 12087 } 12088 } 12089 12090 boolean sysPkg = (isSystemApp(oldPackage)); 12091 if (sysPkg) { 12092 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 12093 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 12094 } else { 12095 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 12096 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 12097 } 12098 } 12099 12100 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 12101 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 12102 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 12103 String volumeUuid, PackageInstalledInfo res) { 12104 String pkgName = deletedPackage.packageName; 12105 boolean deletedPkg = true; 12106 boolean updatedSettings = false; 12107 12108 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 12109 + deletedPackage); 12110 long origUpdateTime; 12111 if (pkg.mExtras != null) { 12112 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 12113 } else { 12114 origUpdateTime = 0; 12115 } 12116 12117 // First delete the existing package while retaining the data directory 12118 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 12119 res.removedInfo, true)) { 12120 // If the existing package wasn't successfully deleted 12121 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 12122 deletedPkg = false; 12123 } else { 12124 // Successfully deleted the old package; proceed with replace. 12125 12126 // If deleted package lived in a container, give users a chance to 12127 // relinquish resources before killing. 12128 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 12129 if (DEBUG_INSTALL) { 12130 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 12131 } 12132 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 12133 final ArrayList<String> pkgList = new ArrayList<String>(1); 12134 pkgList.add(deletedPackage.applicationInfo.packageName); 12135 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 12136 } 12137 12138 deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName); 12139 try { 12140 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 12141 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 12142 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 12143 perUserInstalled, res, user); 12144 updatedSettings = true; 12145 } catch (PackageManagerException e) { 12146 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12147 } 12148 } 12149 12150 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12151 // remove package from internal structures. Note that we want deletePackageX to 12152 // delete the package data and cache directories that it created in 12153 // scanPackageLocked, unless those directories existed before we even tried to 12154 // install. 12155 if(updatedSettings) { 12156 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 12157 deletePackageLI( 12158 pkgName, null, true, allUsers, perUserInstalled, 12159 PackageManager.DELETE_KEEP_DATA, 12160 res.removedInfo, true); 12161 } 12162 // Since we failed to install the new package we need to restore the old 12163 // package that we deleted. 12164 if (deletedPkg) { 12165 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 12166 File restoreFile = new File(deletedPackage.codePath); 12167 // Parse old package 12168 boolean oldExternal = isExternal(deletedPackage); 12169 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 12170 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 12171 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 12172 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 12173 try { 12174 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 12175 null); 12176 } catch (PackageManagerException e) { 12177 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 12178 + e.getMessage()); 12179 return; 12180 } 12181 // Restore of old package succeeded. Update permissions. 12182 // writer 12183 synchronized (mPackages) { 12184 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 12185 UPDATE_PERMISSIONS_ALL); 12186 // can downgrade to reader 12187 mSettings.writeLPr(); 12188 } 12189 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 12190 } 12191 } 12192 } 12193 12194 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 12195 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 12196 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 12197 String volumeUuid, PackageInstalledInfo res) { 12198 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 12199 + ", old=" + deletedPackage); 12200 boolean disabledSystem = false; 12201 boolean updatedSettings = false; 12202 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 12203 if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 12204 != 0) { 12205 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 12206 } 12207 String packageName = deletedPackage.packageName; 12208 if (packageName == null) { 12209 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 12210 "Attempt to delete null packageName."); 12211 return; 12212 } 12213 PackageParser.Package oldPkg; 12214 PackageSetting oldPkgSetting; 12215 // reader 12216 synchronized (mPackages) { 12217 oldPkg = mPackages.get(packageName); 12218 oldPkgSetting = mSettings.mPackages.get(packageName); 12219 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 12220 (oldPkgSetting == null)) { 12221 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 12222 "Couldn't find package:" + packageName + " information"); 12223 return; 12224 } 12225 } 12226 12227 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 12228 12229 res.removedInfo.uid = oldPkg.applicationInfo.uid; 12230 res.removedInfo.removedPackage = packageName; 12231 // Remove existing system package 12232 removePackageLI(oldPkgSetting, true); 12233 // writer 12234 synchronized (mPackages) { 12235 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 12236 if (!disabledSystem && deletedPackage != null) { 12237 // We didn't need to disable the .apk as a current system package, 12238 // which means we are replacing another update that is already 12239 // installed. We need to make sure to delete the older one's .apk. 12240 res.removedInfo.args = createInstallArgsForExisting(0, 12241 deletedPackage.applicationInfo.getCodePath(), 12242 deletedPackage.applicationInfo.getResourcePath(), 12243 getAppDexInstructionSets(deletedPackage.applicationInfo)); 12244 } else { 12245 res.removedInfo.args = null; 12246 } 12247 } 12248 12249 // Successfully disabled the old package. Now proceed with re-installation 12250 deleteCodeCacheDirsLI(pkg.volumeUuid, packageName); 12251 12252 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12253 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 12254 12255 PackageParser.Package newPackage = null; 12256 try { 12257 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 12258 if (newPackage.mExtras != null) { 12259 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 12260 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 12261 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 12262 12263 // is the update attempting to change shared user? that isn't going to work... 12264 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 12265 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 12266 "Forbidding shared user change from " + oldPkgSetting.sharedUser 12267 + " to " + newPkgSetting.sharedUser); 12268 updatedSettings = true; 12269 } 12270 } 12271 12272 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12273 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 12274 perUserInstalled, res, user); 12275 updatedSettings = true; 12276 } 12277 12278 } catch (PackageManagerException e) { 12279 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12280 } 12281 12282 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12283 // Re installation failed. Restore old information 12284 // Remove new pkg information 12285 if (newPackage != null) { 12286 removeInstalledPackageLI(newPackage, true); 12287 } 12288 // Add back the old system package 12289 try { 12290 scanPackageTracedLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 12291 } catch (PackageManagerException e) { 12292 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 12293 } 12294 // Restore the old system information in Settings 12295 synchronized (mPackages) { 12296 if (disabledSystem) { 12297 mSettings.enableSystemPackageLPw(packageName); 12298 } 12299 if (updatedSettings) { 12300 mSettings.setInstallerPackageName(packageName, 12301 oldPkgSetting.installerPackageName); 12302 } 12303 mSettings.writeLPr(); 12304 } 12305 } 12306 } 12307 12308 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 12309 // Collect all used permissions in the UID 12310 ArraySet<String> usedPermissions = new ArraySet<>(); 12311 final int packageCount = su.packages.size(); 12312 for (int i = 0; i < packageCount; i++) { 12313 PackageSetting ps = su.packages.valueAt(i); 12314 if (ps.pkg == null) { 12315 continue; 12316 } 12317 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 12318 for (int j = 0; j < requestedPermCount; j++) { 12319 String permission = ps.pkg.requestedPermissions.get(j); 12320 BasePermission bp = mSettings.mPermissions.get(permission); 12321 if (bp != null) { 12322 usedPermissions.add(permission); 12323 } 12324 } 12325 } 12326 12327 PermissionsState permissionsState = su.getPermissionsState(); 12328 // Prune install permissions 12329 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 12330 final int installPermCount = installPermStates.size(); 12331 for (int i = installPermCount - 1; i >= 0; i--) { 12332 PermissionState permissionState = installPermStates.get(i); 12333 if (!usedPermissions.contains(permissionState.getName())) { 12334 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 12335 if (bp != null) { 12336 permissionsState.revokeInstallPermission(bp); 12337 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 12338 PackageManager.MASK_PERMISSION_FLAGS, 0); 12339 } 12340 } 12341 } 12342 12343 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 12344 12345 // Prune runtime permissions 12346 for (int userId : allUserIds) { 12347 List<PermissionState> runtimePermStates = permissionsState 12348 .getRuntimePermissionStates(userId); 12349 final int runtimePermCount = runtimePermStates.size(); 12350 for (int i = runtimePermCount - 1; i >= 0; i--) { 12351 PermissionState permissionState = runtimePermStates.get(i); 12352 if (!usedPermissions.contains(permissionState.getName())) { 12353 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 12354 if (bp != null) { 12355 permissionsState.revokeRuntimePermission(bp, userId); 12356 permissionsState.updatePermissionFlags(bp, userId, 12357 PackageManager.MASK_PERMISSION_FLAGS, 0); 12358 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 12359 runtimePermissionChangedUserIds, userId); 12360 } 12361 } 12362 } 12363 } 12364 12365 return runtimePermissionChangedUserIds; 12366 } 12367 12368 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 12369 String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, 12370 UserHandle user) { 12371 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 12372 12373 String pkgName = newPackage.packageName; 12374 synchronized (mPackages) { 12375 //write settings. the installStatus will be incomplete at this stage. 12376 //note that the new package setting would have already been 12377 //added to mPackages. It hasn't been persisted yet. 12378 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 12379 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 12380 mSettings.writeLPr(); 12381 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12382 } 12383 12384 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 12385 synchronized (mPackages) { 12386 updatePermissionsLPw(newPackage.packageName, newPackage, 12387 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 12388 ? UPDATE_PERMISSIONS_ALL : 0)); 12389 // For system-bundled packages, we assume that installing an upgraded version 12390 // of the package implies that the user actually wants to run that new code, 12391 // so we enable the package. 12392 PackageSetting ps = mSettings.mPackages.get(pkgName); 12393 if (ps != null) { 12394 if (isSystemApp(newPackage)) { 12395 // NB: implicit assumption that system package upgrades apply to all users 12396 if (DEBUG_INSTALL) { 12397 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 12398 } 12399 if (res.origUsers != null) { 12400 for (int userHandle : res.origUsers) { 12401 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 12402 userHandle, installerPackageName); 12403 } 12404 } 12405 // Also convey the prior install/uninstall state 12406 if (allUsers != null && perUserInstalled != null) { 12407 for (int i = 0; i < allUsers.length; i++) { 12408 if (DEBUG_INSTALL) { 12409 Slog.d(TAG, " user " + allUsers[i] 12410 + " => " + perUserInstalled[i]); 12411 } 12412 ps.setInstalled(perUserInstalled[i], allUsers[i]); 12413 } 12414 // these install state changes will be persisted in the 12415 // upcoming call to mSettings.writeLPr(). 12416 } 12417 } 12418 // It's implied that when a user requests installation, they want the app to be 12419 // installed and enabled. 12420 int userId = user.getIdentifier(); 12421 if (userId != UserHandle.USER_ALL) { 12422 ps.setInstalled(true, userId); 12423 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 12424 } 12425 } 12426 res.name = pkgName; 12427 res.uid = newPackage.applicationInfo.uid; 12428 res.pkg = newPackage; 12429 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 12430 mSettings.setInstallerPackageName(pkgName, installerPackageName); 12431 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12432 //to update install status 12433 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 12434 mSettings.writeLPr(); 12435 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12436 } 12437 12438 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12439 } 12440 12441 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 12442 try { 12443 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 12444 installPackageLI(args, res); 12445 } finally { 12446 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12447 } 12448 } 12449 12450 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 12451 final int installFlags = args.installFlags; 12452 final String installerPackageName = args.installerPackageName; 12453 final String volumeUuid = args.volumeUuid; 12454 final File tmpPackageFile = new File(args.getCodePath()); 12455 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 12456 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 12457 || (args.volumeUuid != null)); 12458 final boolean quickInstall = ((installFlags & PackageManager.INSTALL_QUICK) != 0); 12459 boolean replace = false; 12460 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 12461 if (args.move != null) { 12462 // moving a complete application; perfom an initial scan on the new install location 12463 scanFlags |= SCAN_INITIAL; 12464 } 12465 // Result object to be returned 12466 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12467 12468 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 12469 12470 // Retrieve PackageSettings and parse package 12471 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 12472 | PackageParser.PARSE_ENFORCE_CODE 12473 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 12474 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 12475 | (quickInstall ? PackageParser.PARSE_SKIP_VERIFICATION : 0); 12476 PackageParser pp = new PackageParser(); 12477 pp.setSeparateProcesses(mSeparateProcesses); 12478 pp.setDisplayMetrics(mMetrics); 12479 12480 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 12481 final PackageParser.Package pkg; 12482 try { 12483 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 12484 } catch (PackageParserException e) { 12485 res.setError("Failed parse during installPackageLI", e); 12486 return; 12487 } finally { 12488 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12489 } 12490 12491 // Mark that we have an install time CPU ABI override. 12492 pkg.cpuAbiOverride = args.abiOverride; 12493 12494 String pkgName = res.name = pkg.packageName; 12495 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 12496 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 12497 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 12498 return; 12499 } 12500 } 12501 12502 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 12503 try { 12504 pp.collectCertificates(pkg, parseFlags); 12505 } catch (PackageParserException e) { 12506 res.setError("Failed collect during installPackageLI", e); 12507 return; 12508 } finally { 12509 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12510 } 12511 12512 /* If the installer passed in a manifest digest, compare it now. */ 12513 if (args.manifestDigest != null) { 12514 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectManifestDigest"); 12515 try { 12516 pp.collectManifestDigest(pkg); 12517 } catch (PackageParserException e) { 12518 res.setError("Failed collect during installPackageLI", e); 12519 return; 12520 } finally { 12521 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12522 } 12523 12524 if (DEBUG_INSTALL) { 12525 final String parsedManifest = pkg.manifestDigest == null ? "null" 12526 : pkg.manifestDigest.toString(); 12527 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 12528 + parsedManifest); 12529 } 12530 12531 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 12532 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 12533 return; 12534 } 12535 } else if (DEBUG_INSTALL) { 12536 final String parsedManifest = pkg.manifestDigest == null 12537 ? "null" : pkg.manifestDigest.toString(); 12538 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 12539 } 12540 12541 // Get rid of all references to package scan path via parser. 12542 pp = null; 12543 String oldCodePath = null; 12544 boolean systemApp = false; 12545 synchronized (mPackages) { 12546 // Check if installing already existing package 12547 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12548 String oldName = mSettings.mRenamedPackages.get(pkgName); 12549 if (pkg.mOriginalPackages != null 12550 && pkg.mOriginalPackages.contains(oldName) 12551 && mPackages.containsKey(oldName)) { 12552 // This package is derived from an original package, 12553 // and this device has been updating from that original 12554 // name. We must continue using the original name, so 12555 // rename the new package here. 12556 pkg.setPackageName(oldName); 12557 pkgName = pkg.packageName; 12558 replace = true; 12559 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 12560 + oldName + " pkgName=" + pkgName); 12561 } else if (mPackages.containsKey(pkgName)) { 12562 // This package, under its official name, already exists 12563 // on the device; we should replace it. 12564 replace = true; 12565 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 12566 } 12567 12568 // Prevent apps opting out from runtime permissions 12569 if (replace) { 12570 PackageParser.Package oldPackage = mPackages.get(pkgName); 12571 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 12572 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 12573 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 12574 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 12575 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 12576 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 12577 + " doesn't support runtime permissions but the old" 12578 + " target SDK " + oldTargetSdk + " does."); 12579 return; 12580 } 12581 } 12582 } 12583 12584 PackageSetting ps = mSettings.mPackages.get(pkgName); 12585 if (ps != null) { 12586 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 12587 12588 // Quick sanity check that we're signed correctly if updating; 12589 // we'll check this again later when scanning, but we want to 12590 // bail early here before tripping over redefined permissions. 12591 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 12592 if (!checkUpgradeKeySetLP(ps, pkg)) { 12593 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 12594 + pkg.packageName + " upgrade keys do not match the " 12595 + "previously installed version"); 12596 return; 12597 } 12598 } else { 12599 try { 12600 verifySignaturesLP(ps, pkg); 12601 } catch (PackageManagerException e) { 12602 res.setError(e.error, e.getMessage()); 12603 return; 12604 } 12605 } 12606 12607 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 12608 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 12609 systemApp = (ps.pkg.applicationInfo.flags & 12610 ApplicationInfo.FLAG_SYSTEM) != 0; 12611 } 12612 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 12613 } 12614 12615 // Check whether the newly-scanned package wants to define an already-defined perm 12616 int N = pkg.permissions.size(); 12617 for (int i = N-1; i >= 0; i--) { 12618 PackageParser.Permission perm = pkg.permissions.get(i); 12619 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 12620 if (bp != null) { 12621 // If the defining package is signed with our cert, it's okay. This 12622 // also includes the "updating the same package" case, of course. 12623 // "updating same package" could also involve key-rotation. 12624 final boolean sigsOk; 12625 if (bp.sourcePackage.equals(pkg.packageName) 12626 && (bp.packageSetting instanceof PackageSetting) 12627 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 12628 scanFlags))) { 12629 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 12630 } else { 12631 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 12632 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 12633 } 12634 if (!sigsOk) { 12635 // If the owning package is the system itself, we log but allow 12636 // install to proceed; we fail the install on all other permission 12637 // redefinitions. 12638 if (!bp.sourcePackage.equals("android")) { 12639 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 12640 + pkg.packageName + " attempting to redeclare permission " 12641 + perm.info.name + " already owned by " + bp.sourcePackage); 12642 res.origPermission = perm.info.name; 12643 res.origPackage = bp.sourcePackage; 12644 return; 12645 } else { 12646 Slog.w(TAG, "Package " + pkg.packageName 12647 + " attempting to redeclare system permission " 12648 + perm.info.name + "; ignoring new declaration"); 12649 pkg.permissions.remove(i); 12650 } 12651 } 12652 } 12653 } 12654 12655 } 12656 12657 if (systemApp && onExternal) { 12658 // Disable updates to system apps on sdcard 12659 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 12660 "Cannot install updates to system apps on sdcard"); 12661 return; 12662 } 12663 12664 if (args.move != null) { 12665 // We did an in-place move, so dex is ready to roll 12666 scanFlags |= SCAN_NO_DEX; 12667 scanFlags |= SCAN_MOVE; 12668 12669 synchronized (mPackages) { 12670 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12671 if (ps == null) { 12672 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 12673 "Missing settings for moved package " + pkgName); 12674 } 12675 12676 // We moved the entire application as-is, so bring over the 12677 // previously derived ABI information. 12678 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 12679 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 12680 } 12681 12682 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 12683 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 12684 scanFlags |= SCAN_NO_DEX; 12685 12686 try { 12687 derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride, 12688 true /* extract libs */); 12689 } catch (PackageManagerException pme) { 12690 Slog.e(TAG, "Error deriving application ABI", pme); 12691 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 12692 return; 12693 } 12694 12695 // Run dexopt before old package gets removed, to minimize time when app is unavailable 12696 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 12697 12698 int result = mPackageDexOptimizer 12699 .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */, 12700 false /* defer */, false /* inclDependencies */, 12701 true /*bootComplete*/, quickInstall /*useJit*/); 12702 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12703 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 12704 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); 12705 return; 12706 } 12707 } 12708 12709 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 12710 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 12711 return; 12712 } 12713 12714 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 12715 12716 if (replace) { 12717 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 12718 installerPackageName, volumeUuid, res); 12719 } else { 12720 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 12721 args.user, installerPackageName, volumeUuid, res); 12722 } 12723 synchronized (mPackages) { 12724 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12725 if (ps != null) { 12726 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 12727 } 12728 } 12729 } 12730 12731 private void startIntentFilterVerifications(int userId, boolean replacing, 12732 PackageParser.Package pkg) { 12733 if (mIntentFilterVerifierComponent == null) { 12734 Slog.w(TAG, "No IntentFilter verification will not be done as " 12735 + "there is no IntentFilterVerifier available!"); 12736 return; 12737 } 12738 12739 final int verifierUid = getPackageUid( 12740 mIntentFilterVerifierComponent.getPackageName(), 12741 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 12742 12743 mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); 12744 final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 12745 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 12746 mHandler.sendMessage(msg); 12747 } 12748 12749 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 12750 PackageParser.Package pkg) { 12751 int size = pkg.activities.size(); 12752 if (size == 0) { 12753 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12754 "No activity, so no need to verify any IntentFilter!"); 12755 return; 12756 } 12757 12758 final boolean hasDomainURLs = hasDomainURLs(pkg); 12759 if (!hasDomainURLs) { 12760 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12761 "No domain URLs, so no need to verify any IntentFilter!"); 12762 return; 12763 } 12764 12765 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 12766 + " if any IntentFilter from the " + size 12767 + " Activities needs verification ..."); 12768 12769 int count = 0; 12770 final String packageName = pkg.packageName; 12771 12772 synchronized (mPackages) { 12773 // If this is a new install and we see that we've already run verification for this 12774 // package, we have nothing to do: it means the state was restored from backup. 12775 if (!replacing) { 12776 IntentFilterVerificationInfo ivi = 12777 mSettings.getIntentFilterVerificationLPr(packageName); 12778 if (ivi != null) { 12779 if (DEBUG_DOMAIN_VERIFICATION) { 12780 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 12781 + ivi.getStatusString()); 12782 } 12783 return; 12784 } 12785 } 12786 12787 // If any filters need to be verified, then all need to be. 12788 boolean needToVerify = false; 12789 for (PackageParser.Activity a : pkg.activities) { 12790 for (ActivityIntentInfo filter : a.intents) { 12791 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 12792 if (DEBUG_DOMAIN_VERIFICATION) { 12793 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 12794 } 12795 needToVerify = true; 12796 break; 12797 } 12798 } 12799 } 12800 12801 if (needToVerify) { 12802 final int verificationId = mIntentFilterVerificationToken++; 12803 for (PackageParser.Activity a : pkg.activities) { 12804 for (ActivityIntentInfo filter : a.intents) { 12805 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 12806 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12807 "Verification needed for IntentFilter:" + filter.toString()); 12808 mIntentFilterVerifier.addOneIntentFilterVerification( 12809 verifierUid, userId, verificationId, filter, packageName); 12810 count++; 12811 } 12812 } 12813 } 12814 } 12815 } 12816 12817 if (count > 0) { 12818 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 12819 + " IntentFilter verification" + (count > 1 ? "s" : "") 12820 + " for userId:" + userId); 12821 mIntentFilterVerifier.startVerifications(userId); 12822 } else { 12823 if (DEBUG_DOMAIN_VERIFICATION) { 12824 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 12825 } 12826 } 12827 } 12828 12829 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 12830 final ComponentName cn = filter.activity.getComponentName(); 12831 final String packageName = cn.getPackageName(); 12832 12833 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 12834 packageName); 12835 if (ivi == null) { 12836 return true; 12837 } 12838 int status = ivi.getStatus(); 12839 switch (status) { 12840 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 12841 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 12842 return true; 12843 12844 default: 12845 // Nothing to do 12846 return false; 12847 } 12848 } 12849 12850 private static boolean isMultiArch(PackageSetting ps) { 12851 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 12852 } 12853 12854 private static boolean isMultiArch(ApplicationInfo info) { 12855 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 12856 } 12857 12858 private static boolean isExternal(PackageParser.Package pkg) { 12859 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12860 } 12861 12862 private static boolean isExternal(PackageSetting ps) { 12863 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12864 } 12865 12866 private static boolean isExternal(ApplicationInfo info) { 12867 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12868 } 12869 12870 private static boolean isSystemApp(PackageParser.Package pkg) { 12871 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12872 } 12873 12874 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 12875 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 12876 } 12877 12878 private static boolean hasDomainURLs(PackageParser.Package pkg) { 12879 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 12880 } 12881 12882 private static boolean isSystemApp(PackageSetting ps) { 12883 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 12884 } 12885 12886 private static boolean isUpdatedSystemApp(PackageSetting ps) { 12887 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 12888 } 12889 12890 private int packageFlagsToInstallFlags(PackageSetting ps) { 12891 int installFlags = 0; 12892 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 12893 // This existing package was an external ASEC install when we have 12894 // the external flag without a UUID 12895 installFlags |= PackageManager.INSTALL_EXTERNAL; 12896 } 12897 if (ps.isForwardLocked()) { 12898 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 12899 } 12900 return installFlags; 12901 } 12902 12903 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 12904 if (isExternal(pkg)) { 12905 if (TextUtils.isEmpty(pkg.volumeUuid)) { 12906 return StorageManager.UUID_PRIMARY_PHYSICAL; 12907 } else { 12908 return pkg.volumeUuid; 12909 } 12910 } else { 12911 return StorageManager.UUID_PRIVATE_INTERNAL; 12912 } 12913 } 12914 12915 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 12916 if (isExternal(pkg)) { 12917 if (TextUtils.isEmpty(pkg.volumeUuid)) { 12918 return mSettings.getExternalVersion(); 12919 } else { 12920 return mSettings.findOrCreateVersion(pkg.volumeUuid); 12921 } 12922 } else { 12923 return mSettings.getInternalVersion(); 12924 } 12925 } 12926 12927 private void deleteTempPackageFiles() { 12928 final FilenameFilter filter = new FilenameFilter() { 12929 public boolean accept(File dir, String name) { 12930 return name.startsWith("vmdl") && name.endsWith(".tmp"); 12931 } 12932 }; 12933 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 12934 file.delete(); 12935 } 12936 } 12937 12938 @Override 12939 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 12940 int flags) { 12941 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 12942 flags); 12943 } 12944 12945 @Override 12946 public void deletePackage(final String packageName, 12947 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 12948 mContext.enforceCallingOrSelfPermission( 12949 android.Manifest.permission.DELETE_PACKAGES, null); 12950 Preconditions.checkNotNull(packageName); 12951 Preconditions.checkNotNull(observer); 12952 final int uid = Binder.getCallingUid(); 12953 final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0; 12954 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 12955 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 12956 mContext.enforceCallingPermission( 12957 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12958 "deletePackage for user " + userId); 12959 } 12960 12961 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 12962 try { 12963 observer.onPackageDeleted(packageName, 12964 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 12965 } catch (RemoteException re) { 12966 } 12967 return; 12968 } 12969 12970 for (int currentUserId : users) { 12971 if (getBlockUninstallForUser(packageName, currentUserId)) { 12972 try { 12973 observer.onPackageDeleted(packageName, 12974 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 12975 } catch (RemoteException re) { 12976 } 12977 return; 12978 } 12979 } 12980 12981 if (DEBUG_REMOVE) { 12982 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 12983 } 12984 // Queue up an async operation since the package deletion may take a little while. 12985 mHandler.post(new Runnable() { 12986 public void run() { 12987 mHandler.removeCallbacks(this); 12988 final int returnCode = deletePackageX(packageName, userId, flags); 12989 try { 12990 observer.onPackageDeleted(packageName, returnCode, null); 12991 } catch (RemoteException e) { 12992 Log.i(TAG, "Observer no longer exists."); 12993 } //end catch 12994 } //end run 12995 }); 12996 } 12997 12998 private boolean isPackageDeviceAdmin(String packageName, int userId) { 12999 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 13000 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 13001 try { 13002 if (dpm != null) { 13003 // Does the package contains the device owner? 13004 if (dpm.isDeviceOwnerPackage(packageName)) { 13005 return true; 13006 } 13007 // Does it contain a device admin for any user? 13008 int[] users; 13009 if (userId == UserHandle.USER_ALL) { 13010 users = sUserManager.getUserIds(); 13011 } else { 13012 users = new int[]{userId}; 13013 } 13014 for (int i = 0; i < users.length; ++i) { 13015 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 13016 return true; 13017 } 13018 } 13019 } 13020 } catch (RemoteException e) { 13021 } 13022 return false; 13023 } 13024 13025 /** 13026 * This method is an internal method that could be get invoked either 13027 * to delete an installed package or to clean up a failed installation. 13028 * After deleting an installed package, a broadcast is sent to notify any 13029 * listeners that the package has been installed. For cleaning up a failed 13030 * installation, the broadcast is not necessary since the package's 13031 * installation wouldn't have sent the initial broadcast either 13032 * The key steps in deleting a package are 13033 * deleting the package information in internal structures like mPackages, 13034 * deleting the packages base directories through installd 13035 * updating mSettings to reflect current status 13036 * persisting settings for later use 13037 * sending a broadcast if necessary 13038 */ 13039 private int deletePackageX(String packageName, int userId, int flags) { 13040 final PackageRemovedInfo info = new PackageRemovedInfo(); 13041 final boolean res; 13042 13043 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 13044 ? UserHandle.ALL : new UserHandle(userId); 13045 13046 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 13047 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 13048 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 13049 } 13050 13051 boolean removedForAllUsers = false; 13052 boolean systemUpdate = false; 13053 13054 // for the uninstall-updates case and restricted profiles, remember the per- 13055 // userhandle installed state 13056 int[] allUsers; 13057 boolean[] perUserInstalled; 13058 synchronized (mPackages) { 13059 PackageSetting ps = mSettings.mPackages.get(packageName); 13060 allUsers = sUserManager.getUserIds(); 13061 perUserInstalled = new boolean[allUsers.length]; 13062 for (int i = 0; i < allUsers.length; i++) { 13063 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 13064 } 13065 } 13066 13067 synchronized (mInstallLock) { 13068 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 13069 res = deletePackageLI(packageName, removeForUser, 13070 true, allUsers, perUserInstalled, 13071 flags | REMOVE_CHATTY, info, true); 13072 systemUpdate = info.isRemovedPackageSystemUpdate; 13073 if (res && !systemUpdate && mPackages.get(packageName) == null) { 13074 removedForAllUsers = true; 13075 } 13076 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 13077 + " removedForAllUsers=" + removedForAllUsers); 13078 } 13079 13080 if (res) { 13081 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 13082 13083 // If the removed package was a system update, the old system package 13084 // was re-enabled; we need to broadcast this information 13085 if (systemUpdate) { 13086 Bundle extras = new Bundle(1); 13087 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 13088 ? info.removedAppId : info.uid); 13089 extras.putBoolean(Intent.EXTRA_REPLACING, true); 13090 13091 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 13092 extras, null, null, null); 13093 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 13094 extras, null, null, null); 13095 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 13096 null, packageName, null, null); 13097 } 13098 } 13099 // Force a gc here. 13100 Runtime.getRuntime().gc(); 13101 // Delete the resources here after sending the broadcast to let 13102 // other processes clean up before deleting resources. 13103 if (info.args != null) { 13104 synchronized (mInstallLock) { 13105 info.args.doPostDeleteLI(true); 13106 } 13107 } 13108 13109 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 13110 } 13111 13112 class PackageRemovedInfo { 13113 String removedPackage; 13114 int uid = -1; 13115 int removedAppId = -1; 13116 int[] removedUsers = null; 13117 boolean isRemovedPackageSystemUpdate = false; 13118 // Clean up resources deleted packages. 13119 InstallArgs args = null; 13120 13121 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 13122 Bundle extras = new Bundle(1); 13123 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 13124 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 13125 if (replacing) { 13126 extras.putBoolean(Intent.EXTRA_REPLACING, true); 13127 } 13128 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 13129 if (removedPackage != null) { 13130 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 13131 extras, null, null, removedUsers); 13132 if (fullRemove && !replacing) { 13133 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 13134 extras, null, null, removedUsers); 13135 } 13136 } 13137 if (removedAppId >= 0) { 13138 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 13139 removedUsers); 13140 } 13141 } 13142 } 13143 13144 /* 13145 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 13146 * flag is not set, the data directory is removed as well. 13147 * make sure this flag is set for partially installed apps. If not its meaningless to 13148 * delete a partially installed application. 13149 */ 13150 private void removePackageDataLI(PackageSetting ps, 13151 int[] allUserHandles, boolean[] perUserInstalled, 13152 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 13153 String packageName = ps.name; 13154 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 13155 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 13156 // Retrieve object to delete permissions for shared user later on 13157 final PackageSetting deletedPs; 13158 // reader 13159 synchronized (mPackages) { 13160 deletedPs = mSettings.mPackages.get(packageName); 13161 if (outInfo != null) { 13162 outInfo.removedPackage = packageName; 13163 outInfo.removedUsers = deletedPs != null 13164 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 13165 : null; 13166 } 13167 } 13168 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 13169 removeDataDirsLI(ps.volumeUuid, packageName); 13170 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 13171 } 13172 // writer 13173 synchronized (mPackages) { 13174 if (deletedPs != null) { 13175 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 13176 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 13177 clearDefaultBrowserIfNeeded(packageName); 13178 if (outInfo != null) { 13179 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 13180 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 13181 } 13182 updatePermissionsLPw(deletedPs.name, null, 0); 13183 if (deletedPs.sharedUser != null) { 13184 // Remove permissions associated with package. Since runtime 13185 // permissions are per user we have to kill the removed package 13186 // or packages running under the shared user of the removed 13187 // package if revoking the permissions requested only by the removed 13188 // package is successful and this causes a change in gids. 13189 for (int userId : UserManagerService.getInstance().getUserIds()) { 13190 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 13191 userId); 13192 if (userIdToKill == UserHandle.USER_ALL 13193 || userIdToKill >= UserHandle.USER_SYSTEM) { 13194 // If gids changed for this user, kill all affected packages. 13195 mHandler.post(new Runnable() { 13196 @Override 13197 public void run() { 13198 // This has to happen with no lock held. 13199 killApplication(deletedPs.name, deletedPs.appId, 13200 KILL_APP_REASON_GIDS_CHANGED); 13201 } 13202 }); 13203 break; 13204 } 13205 } 13206 } 13207 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 13208 } 13209 // make sure to preserve per-user disabled state if this removal was just 13210 // a downgrade of a system app to the factory package 13211 if (allUserHandles != null && perUserInstalled != null) { 13212 if (DEBUG_REMOVE) { 13213 Slog.d(TAG, "Propagating install state across downgrade"); 13214 } 13215 for (int i = 0; i < allUserHandles.length; i++) { 13216 if (DEBUG_REMOVE) { 13217 Slog.d(TAG, " user " + allUserHandles[i] 13218 + " => " + perUserInstalled[i]); 13219 } 13220 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 13221 } 13222 } 13223 } 13224 // can downgrade to reader 13225 if (writeSettings) { 13226 // Save settings now 13227 mSettings.writeLPr(); 13228 } 13229 } 13230 if (outInfo != null) { 13231 // A user ID was deleted here. Go through all users and remove it 13232 // from KeyStore. 13233 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 13234 } 13235 } 13236 13237 static boolean locationIsPrivileged(File path) { 13238 try { 13239 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 13240 .getCanonicalPath(); 13241 return path.getCanonicalPath().startsWith(privilegedAppDir); 13242 } catch (IOException e) { 13243 Slog.e(TAG, "Unable to access code path " + path); 13244 } 13245 return false; 13246 } 13247 13248 /* 13249 * Tries to delete system package. 13250 */ 13251 private boolean deleteSystemPackageLI(PackageSetting newPs, 13252 int[] allUserHandles, boolean[] perUserInstalled, 13253 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 13254 final boolean applyUserRestrictions 13255 = (allUserHandles != null) && (perUserInstalled != null); 13256 PackageSetting disabledPs = null; 13257 // Confirm if the system package has been updated 13258 // An updated system app can be deleted. This will also have to restore 13259 // the system pkg from system partition 13260 // reader 13261 synchronized (mPackages) { 13262 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 13263 } 13264 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 13265 + " disabledPs=" + disabledPs); 13266 if (disabledPs == null) { 13267 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 13268 return false; 13269 } else if (DEBUG_REMOVE) { 13270 Slog.d(TAG, "Deleting system pkg from data partition"); 13271 } 13272 if (DEBUG_REMOVE) { 13273 if (applyUserRestrictions) { 13274 Slog.d(TAG, "Remembering install states:"); 13275 for (int i = 0; i < allUserHandles.length; i++) { 13276 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 13277 } 13278 } 13279 } 13280 // Delete the updated package 13281 outInfo.isRemovedPackageSystemUpdate = true; 13282 if (disabledPs.versionCode < newPs.versionCode) { 13283 // Delete data for downgrades 13284 flags &= ~PackageManager.DELETE_KEEP_DATA; 13285 } else { 13286 // Preserve data by setting flag 13287 flags |= PackageManager.DELETE_KEEP_DATA; 13288 } 13289 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 13290 allUserHandles, perUserInstalled, outInfo, writeSettings); 13291 if (!ret) { 13292 return false; 13293 } 13294 // writer 13295 synchronized (mPackages) { 13296 // Reinstate the old system package 13297 mSettings.enableSystemPackageLPw(newPs.name); 13298 // Remove any native libraries from the upgraded package. 13299 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 13300 } 13301 // Install the system package 13302 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 13303 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 13304 if (locationIsPrivileged(disabledPs.codePath)) { 13305 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13306 } 13307 13308 final PackageParser.Package newPkg; 13309 try { 13310 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 13311 } catch (PackageManagerException e) { 13312 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 13313 return false; 13314 } 13315 13316 // writer 13317 synchronized (mPackages) { 13318 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 13319 13320 // Propagate the permissions state as we do not want to drop on the floor 13321 // runtime permissions. The update permissions method below will take 13322 // care of removing obsolete permissions and grant install permissions. 13323 ps.getPermissionsState().copyFrom(newPs.getPermissionsState()); 13324 updatePermissionsLPw(newPkg.packageName, newPkg, 13325 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 13326 13327 if (applyUserRestrictions) { 13328 if (DEBUG_REMOVE) { 13329 Slog.d(TAG, "Propagating install state across reinstall"); 13330 } 13331 for (int i = 0; i < allUserHandles.length; i++) { 13332 if (DEBUG_REMOVE) { 13333 Slog.d(TAG, " user " + allUserHandles[i] 13334 + " => " + perUserInstalled[i]); 13335 } 13336 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 13337 13338 mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false); 13339 } 13340 // Regardless of writeSettings we need to ensure that this restriction 13341 // state propagation is persisted 13342 mSettings.writeAllUsersPackageRestrictionsLPr(); 13343 } 13344 // can downgrade to reader here 13345 if (writeSettings) { 13346 mSettings.writeLPr(); 13347 } 13348 } 13349 return true; 13350 } 13351 13352 private boolean deleteInstalledPackageLI(PackageSetting ps, 13353 boolean deleteCodeAndResources, int flags, 13354 int[] allUserHandles, boolean[] perUserInstalled, 13355 PackageRemovedInfo outInfo, boolean writeSettings) { 13356 if (outInfo != null) { 13357 outInfo.uid = ps.appId; 13358 } 13359 13360 // Delete package data from internal structures and also remove data if flag is set 13361 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 13362 13363 // Delete application code and resources 13364 if (deleteCodeAndResources && (outInfo != null)) { 13365 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 13366 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 13367 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 13368 } 13369 return true; 13370 } 13371 13372 @Override 13373 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 13374 int userId) { 13375 mContext.enforceCallingOrSelfPermission( 13376 android.Manifest.permission.DELETE_PACKAGES, null); 13377 synchronized (mPackages) { 13378 PackageSetting ps = mSettings.mPackages.get(packageName); 13379 if (ps == null) { 13380 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 13381 return false; 13382 } 13383 if (!ps.getInstalled(userId)) { 13384 // Can't block uninstall for an app that is not installed or enabled. 13385 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 13386 return false; 13387 } 13388 ps.setBlockUninstall(blockUninstall, userId); 13389 mSettings.writePackageRestrictionsLPr(userId); 13390 } 13391 return true; 13392 } 13393 13394 @Override 13395 public boolean getBlockUninstallForUser(String packageName, int userId) { 13396 synchronized (mPackages) { 13397 PackageSetting ps = mSettings.mPackages.get(packageName); 13398 if (ps == null) { 13399 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 13400 return false; 13401 } 13402 return ps.getBlockUninstall(userId); 13403 } 13404 } 13405 13406 /* 13407 * This method handles package deletion in general 13408 */ 13409 private boolean deletePackageLI(String packageName, UserHandle user, 13410 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 13411 int flags, PackageRemovedInfo outInfo, 13412 boolean writeSettings) { 13413 if (packageName == null) { 13414 Slog.w(TAG, "Attempt to delete null packageName."); 13415 return false; 13416 } 13417 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 13418 PackageSetting ps; 13419 boolean dataOnly = false; 13420 int removeUser = -1; 13421 int appId = -1; 13422 synchronized (mPackages) { 13423 ps = mSettings.mPackages.get(packageName); 13424 if (ps == null) { 13425 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 13426 return false; 13427 } 13428 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 13429 && user.getIdentifier() != UserHandle.USER_ALL) { 13430 // The caller is asking that the package only be deleted for a single 13431 // user. To do this, we just mark its uninstalled state and delete 13432 // its data. If this is a system app, we only allow this to happen if 13433 // they have set the special DELETE_SYSTEM_APP which requests different 13434 // semantics than normal for uninstalling system apps. 13435 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 13436 final int userId = user.getIdentifier(); 13437 ps.setUserState(userId, 13438 COMPONENT_ENABLED_STATE_DEFAULT, 13439 false, //installed 13440 true, //stopped 13441 true, //notLaunched 13442 false, //hidden 13443 null, null, null, 13444 false, // blockUninstall 13445 ps.readUserState(userId).domainVerificationStatus, 0); 13446 if (!isSystemApp(ps)) { 13447 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 13448 // Other user still have this package installed, so all 13449 // we need to do is clear this user's data and save that 13450 // it is uninstalled. 13451 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 13452 removeUser = user.getIdentifier(); 13453 appId = ps.appId; 13454 scheduleWritePackageRestrictionsLocked(removeUser); 13455 } else { 13456 // We need to set it back to 'installed' so the uninstall 13457 // broadcasts will be sent correctly. 13458 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 13459 ps.setInstalled(true, user.getIdentifier()); 13460 } 13461 } else { 13462 // This is a system app, so we assume that the 13463 // other users still have this package installed, so all 13464 // we need to do is clear this user's data and save that 13465 // it is uninstalled. 13466 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 13467 removeUser = user.getIdentifier(); 13468 appId = ps.appId; 13469 scheduleWritePackageRestrictionsLocked(removeUser); 13470 } 13471 } 13472 } 13473 13474 if (removeUser >= 0) { 13475 // From above, we determined that we are deleting this only 13476 // for a single user. Continue the work here. 13477 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 13478 if (outInfo != null) { 13479 outInfo.removedPackage = packageName; 13480 outInfo.removedAppId = appId; 13481 outInfo.removedUsers = new int[] {removeUser}; 13482 } 13483 mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser); 13484 removeKeystoreDataIfNeeded(removeUser, appId); 13485 schedulePackageCleaning(packageName, removeUser, false); 13486 synchronized (mPackages) { 13487 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { 13488 scheduleWritePackageRestrictionsLocked(removeUser); 13489 } 13490 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser); 13491 } 13492 return true; 13493 } 13494 13495 if (dataOnly) { 13496 // Delete application data first 13497 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 13498 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 13499 return true; 13500 } 13501 13502 boolean ret = false; 13503 if (isSystemApp(ps)) { 13504 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 13505 // When an updated system application is deleted we delete the existing resources as well and 13506 // fall back to existing code in system partition 13507 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 13508 flags, outInfo, writeSettings); 13509 } else { 13510 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 13511 // Kill application pre-emptively especially for apps on sd. 13512 killApplication(packageName, ps.appId, "uninstall pkg"); 13513 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 13514 allUserHandles, perUserInstalled, 13515 outInfo, writeSettings); 13516 } 13517 13518 return ret; 13519 } 13520 13521 private final class ClearStorageConnection implements ServiceConnection { 13522 IMediaContainerService mContainerService; 13523 13524 @Override 13525 public void onServiceConnected(ComponentName name, IBinder service) { 13526 synchronized (this) { 13527 mContainerService = IMediaContainerService.Stub.asInterface(service); 13528 notifyAll(); 13529 } 13530 } 13531 13532 @Override 13533 public void onServiceDisconnected(ComponentName name) { 13534 } 13535 } 13536 13537 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 13538 final boolean mounted; 13539 if (Environment.isExternalStorageEmulated()) { 13540 mounted = true; 13541 } else { 13542 final String status = Environment.getExternalStorageState(); 13543 13544 mounted = status.equals(Environment.MEDIA_MOUNTED) 13545 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 13546 } 13547 13548 if (!mounted) { 13549 return; 13550 } 13551 13552 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 13553 int[] users; 13554 if (userId == UserHandle.USER_ALL) { 13555 users = sUserManager.getUserIds(); 13556 } else { 13557 users = new int[] { userId }; 13558 } 13559 final ClearStorageConnection conn = new ClearStorageConnection(); 13560 if (mContext.bindServiceAsUser( 13561 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 13562 try { 13563 for (int curUser : users) { 13564 long timeout = SystemClock.uptimeMillis() + 5000; 13565 synchronized (conn) { 13566 long now = SystemClock.uptimeMillis(); 13567 while (conn.mContainerService == null && now < timeout) { 13568 try { 13569 conn.wait(timeout - now); 13570 } catch (InterruptedException e) { 13571 } 13572 } 13573 } 13574 if (conn.mContainerService == null) { 13575 return; 13576 } 13577 13578 final UserEnvironment userEnv = new UserEnvironment(curUser); 13579 clearDirectory(conn.mContainerService, 13580 userEnv.buildExternalStorageAppCacheDirs(packageName)); 13581 if (allData) { 13582 clearDirectory(conn.mContainerService, 13583 userEnv.buildExternalStorageAppDataDirs(packageName)); 13584 clearDirectory(conn.mContainerService, 13585 userEnv.buildExternalStorageAppMediaDirs(packageName)); 13586 } 13587 } 13588 } finally { 13589 mContext.unbindService(conn); 13590 } 13591 } 13592 } 13593 13594 @Override 13595 public void clearApplicationUserData(final String packageName, 13596 final IPackageDataObserver observer, final int userId) { 13597 mContext.enforceCallingOrSelfPermission( 13598 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 13599 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 13600 // Queue up an async operation since the package deletion may take a little while. 13601 mHandler.post(new Runnable() { 13602 public void run() { 13603 mHandler.removeCallbacks(this); 13604 final boolean succeeded; 13605 synchronized (mInstallLock) { 13606 succeeded = clearApplicationUserDataLI(packageName, userId); 13607 } 13608 clearExternalStorageDataSync(packageName, userId, true); 13609 if (succeeded) { 13610 // invoke DeviceStorageMonitor's update method to clear any notifications 13611 DeviceStorageMonitorInternal 13612 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 13613 if (dsm != null) { 13614 dsm.checkMemory(); 13615 } 13616 } 13617 if(observer != null) { 13618 try { 13619 observer.onRemoveCompleted(packageName, succeeded); 13620 } catch (RemoteException e) { 13621 Log.i(TAG, "Observer no longer exists."); 13622 } 13623 } //end if observer 13624 } //end run 13625 }); 13626 } 13627 13628 private boolean clearApplicationUserDataLI(String packageName, int userId) { 13629 if (packageName == null) { 13630 Slog.w(TAG, "Attempt to delete null packageName."); 13631 return false; 13632 } 13633 13634 // Try finding details about the requested package 13635 PackageParser.Package pkg; 13636 synchronized (mPackages) { 13637 pkg = mPackages.get(packageName); 13638 if (pkg == null) { 13639 final PackageSetting ps = mSettings.mPackages.get(packageName); 13640 if (ps != null) { 13641 pkg = ps.pkg; 13642 } 13643 } 13644 13645 if (pkg == null) { 13646 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 13647 return false; 13648 } 13649 13650 PackageSetting ps = (PackageSetting) pkg.mExtras; 13651 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 13652 } 13653 13654 // Always delete data directories for package, even if we found no other 13655 // record of app. This helps users recover from UID mismatches without 13656 // resorting to a full data wipe. 13657 int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId); 13658 if (retCode < 0) { 13659 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 13660 return false; 13661 } 13662 13663 final int appId = pkg.applicationInfo.uid; 13664 removeKeystoreDataIfNeeded(userId, appId); 13665 13666 // Create a native library symlink only if we have native libraries 13667 // and if the native libraries are 32 bit libraries. We do not provide 13668 // this symlink for 64 bit libraries. 13669 if (pkg.applicationInfo.primaryCpuAbi != null && 13670 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 13671 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 13672 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 13673 nativeLibPath, userId) < 0) { 13674 Slog.w(TAG, "Failed linking native library dir"); 13675 return false; 13676 } 13677 } 13678 13679 return true; 13680 } 13681 13682 /** 13683 * Reverts user permission state changes (permissions and flags) in 13684 * all packages for a given user. 13685 * 13686 * @param userId The device user for which to do a reset. 13687 */ 13688 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 13689 final int packageCount = mPackages.size(); 13690 for (int i = 0; i < packageCount; i++) { 13691 PackageParser.Package pkg = mPackages.valueAt(i); 13692 PackageSetting ps = (PackageSetting) pkg.mExtras; 13693 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 13694 } 13695 } 13696 13697 /** 13698 * Reverts user permission state changes (permissions and flags). 13699 * 13700 * @param ps The package for which to reset. 13701 * @param userId The device user for which to do a reset. 13702 */ 13703 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 13704 final PackageSetting ps, final int userId) { 13705 if (ps.pkg == null) { 13706 return; 13707 } 13708 13709 final int userSettableFlags = FLAG_PERMISSION_USER_SET 13710 | FLAG_PERMISSION_USER_FIXED 13711 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 13712 13713 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 13714 | FLAG_PERMISSION_POLICY_FIXED; 13715 13716 boolean writeInstallPermissions = false; 13717 boolean writeRuntimePermissions = false; 13718 13719 final int permissionCount = ps.pkg.requestedPermissions.size(); 13720 for (int i = 0; i < permissionCount; i++) { 13721 String permission = ps.pkg.requestedPermissions.get(i); 13722 13723 BasePermission bp = mSettings.mPermissions.get(permission); 13724 if (bp == null) { 13725 continue; 13726 } 13727 13728 // If shared user we just reset the state to which only this app contributed. 13729 if (ps.sharedUser != null) { 13730 boolean used = false; 13731 final int packageCount = ps.sharedUser.packages.size(); 13732 for (int j = 0; j < packageCount; j++) { 13733 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 13734 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 13735 && pkg.pkg.requestedPermissions.contains(permission)) { 13736 used = true; 13737 break; 13738 } 13739 } 13740 if (used) { 13741 continue; 13742 } 13743 } 13744 13745 PermissionsState permissionsState = ps.getPermissionsState(); 13746 13747 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 13748 13749 // Always clear the user settable flags. 13750 final boolean hasInstallState = permissionsState.getInstallPermissionState( 13751 bp.name) != null; 13752 if (permissionsState.updatePermissionFlags(bp, userId, userSettableFlags, 0)) { 13753 if (hasInstallState) { 13754 writeInstallPermissions = true; 13755 } else { 13756 writeRuntimePermissions = true; 13757 } 13758 } 13759 13760 // Below is only runtime permission handling. 13761 if (!bp.isRuntime()) { 13762 continue; 13763 } 13764 13765 // Never clobber system or policy. 13766 if ((oldFlags & policyOrSystemFlags) != 0) { 13767 continue; 13768 } 13769 13770 // If this permission was granted by default, make sure it is. 13771 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 13772 if (permissionsState.grantRuntimePermission(bp, userId) 13773 != PERMISSION_OPERATION_FAILURE) { 13774 writeRuntimePermissions = true; 13775 } 13776 } else { 13777 // Otherwise, reset the permission. 13778 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 13779 switch (revokeResult) { 13780 case PERMISSION_OPERATION_SUCCESS: { 13781 writeRuntimePermissions = true; 13782 } break; 13783 13784 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 13785 writeRuntimePermissions = true; 13786 final int appId = ps.appId; 13787 mHandler.post(new Runnable() { 13788 @Override 13789 public void run() { 13790 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 13791 } 13792 }); 13793 } break; 13794 } 13795 } 13796 } 13797 13798 // Synchronously write as we are taking permissions away. 13799 if (writeRuntimePermissions) { 13800 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 13801 } 13802 13803 // Synchronously write as we are taking permissions away. 13804 if (writeInstallPermissions) { 13805 mSettings.writeLPr(); 13806 } 13807 } 13808 13809 /** 13810 * Remove entries from the keystore daemon. Will only remove it if the 13811 * {@code appId} is valid. 13812 */ 13813 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 13814 if (appId < 0) { 13815 return; 13816 } 13817 13818 final KeyStore keyStore = KeyStore.getInstance(); 13819 if (keyStore != null) { 13820 if (userId == UserHandle.USER_ALL) { 13821 for (final int individual : sUserManager.getUserIds()) { 13822 keyStore.clearUid(UserHandle.getUid(individual, appId)); 13823 } 13824 } else { 13825 keyStore.clearUid(UserHandle.getUid(userId, appId)); 13826 } 13827 } else { 13828 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 13829 } 13830 } 13831 13832 @Override 13833 public void deleteApplicationCacheFiles(final String packageName, 13834 final IPackageDataObserver observer) { 13835 mContext.enforceCallingOrSelfPermission( 13836 android.Manifest.permission.DELETE_CACHE_FILES, null); 13837 // Queue up an async operation since the package deletion may take a little while. 13838 final int userId = UserHandle.getCallingUserId(); 13839 mHandler.post(new Runnable() { 13840 public void run() { 13841 mHandler.removeCallbacks(this); 13842 final boolean succeded; 13843 synchronized (mInstallLock) { 13844 succeded = deleteApplicationCacheFilesLI(packageName, userId); 13845 } 13846 clearExternalStorageDataSync(packageName, userId, false); 13847 if (observer != null) { 13848 try { 13849 observer.onRemoveCompleted(packageName, succeded); 13850 } catch (RemoteException e) { 13851 Log.i(TAG, "Observer no longer exists."); 13852 } 13853 } //end if observer 13854 } //end run 13855 }); 13856 } 13857 13858 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 13859 if (packageName == null) { 13860 Slog.w(TAG, "Attempt to delete null packageName."); 13861 return false; 13862 } 13863 PackageParser.Package p; 13864 synchronized (mPackages) { 13865 p = mPackages.get(packageName); 13866 } 13867 if (p == null) { 13868 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 13869 return false; 13870 } 13871 final ApplicationInfo applicationInfo = p.applicationInfo; 13872 if (applicationInfo == null) { 13873 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 13874 return false; 13875 } 13876 int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId); 13877 if (retCode < 0) { 13878 Slog.w(TAG, "Couldn't remove cache files for package: " 13879 + packageName + " u" + userId); 13880 return false; 13881 } 13882 return true; 13883 } 13884 13885 @Override 13886 public void getPackageSizeInfo(final String packageName, int userHandle, 13887 final IPackageStatsObserver observer) { 13888 mContext.enforceCallingOrSelfPermission( 13889 android.Manifest.permission.GET_PACKAGE_SIZE, null); 13890 if (packageName == null) { 13891 throw new IllegalArgumentException("Attempt to get size of null packageName"); 13892 } 13893 13894 PackageStats stats = new PackageStats(packageName, userHandle); 13895 13896 /* 13897 * Queue up an async operation since the package measurement may take a 13898 * little while. 13899 */ 13900 Message msg = mHandler.obtainMessage(INIT_COPY); 13901 msg.obj = new MeasureParams(stats, observer); 13902 mHandler.sendMessage(msg); 13903 } 13904 13905 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 13906 PackageStats pStats) { 13907 if (packageName == null) { 13908 Slog.w(TAG, "Attempt to get size of null packageName."); 13909 return false; 13910 } 13911 PackageParser.Package p; 13912 boolean dataOnly = false; 13913 String libDirRoot = null; 13914 String asecPath = null; 13915 PackageSetting ps = null; 13916 synchronized (mPackages) { 13917 p = mPackages.get(packageName); 13918 ps = mSettings.mPackages.get(packageName); 13919 if(p == null) { 13920 dataOnly = true; 13921 if((ps == null) || (ps.pkg == null)) { 13922 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 13923 return false; 13924 } 13925 p = ps.pkg; 13926 } 13927 if (ps != null) { 13928 libDirRoot = ps.legacyNativeLibraryPathString; 13929 } 13930 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 13931 final long token = Binder.clearCallingIdentity(); 13932 try { 13933 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 13934 if (secureContainerId != null) { 13935 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 13936 } 13937 } finally { 13938 Binder.restoreCallingIdentity(token); 13939 } 13940 } 13941 } 13942 String publicSrcDir = null; 13943 if(!dataOnly) { 13944 final ApplicationInfo applicationInfo = p.applicationInfo; 13945 if (applicationInfo == null) { 13946 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 13947 return false; 13948 } 13949 if (p.isForwardLocked()) { 13950 publicSrcDir = applicationInfo.getBaseResourcePath(); 13951 } 13952 } 13953 // TODO: extend to measure size of split APKs 13954 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 13955 // not just the first level. 13956 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 13957 // just the primary. 13958 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 13959 13960 String apkPath; 13961 File packageDir = new File(p.codePath); 13962 13963 if (packageDir.isDirectory() && p.canHaveOatDir()) { 13964 apkPath = packageDir.getAbsolutePath(); 13965 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 13966 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 13967 libDirRoot = null; 13968 } 13969 } else { 13970 apkPath = p.baseCodePath; 13971 } 13972 13973 int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath, 13974 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 13975 if (res < 0) { 13976 return false; 13977 } 13978 13979 // Fix-up for forward-locked applications in ASEC containers. 13980 if (!isExternal(p)) { 13981 pStats.codeSize += pStats.externalCodeSize; 13982 pStats.externalCodeSize = 0L; 13983 } 13984 13985 return true; 13986 } 13987 13988 13989 @Override 13990 public void addPackageToPreferred(String packageName) { 13991 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 13992 } 13993 13994 @Override 13995 public void removePackageFromPreferred(String packageName) { 13996 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 13997 } 13998 13999 @Override 14000 public List<PackageInfo> getPreferredPackages(int flags) { 14001 return new ArrayList<PackageInfo>(); 14002 } 14003 14004 private int getUidTargetSdkVersionLockedLPr(int uid) { 14005 Object obj = mSettings.getUserIdLPr(uid); 14006 if (obj instanceof SharedUserSetting) { 14007 final SharedUserSetting sus = (SharedUserSetting) obj; 14008 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 14009 final Iterator<PackageSetting> it = sus.packages.iterator(); 14010 while (it.hasNext()) { 14011 final PackageSetting ps = it.next(); 14012 if (ps.pkg != null) { 14013 int v = ps.pkg.applicationInfo.targetSdkVersion; 14014 if (v < vers) vers = v; 14015 } 14016 } 14017 return vers; 14018 } else if (obj instanceof PackageSetting) { 14019 final PackageSetting ps = (PackageSetting) obj; 14020 if (ps.pkg != null) { 14021 return ps.pkg.applicationInfo.targetSdkVersion; 14022 } 14023 } 14024 return Build.VERSION_CODES.CUR_DEVELOPMENT; 14025 } 14026 14027 @Override 14028 public void addPreferredActivity(IntentFilter filter, int match, 14029 ComponentName[] set, ComponentName activity, int userId) { 14030 addPreferredActivityInternal(filter, match, set, activity, true, userId, 14031 "Adding preferred"); 14032 } 14033 14034 private void addPreferredActivityInternal(IntentFilter filter, int match, 14035 ComponentName[] set, ComponentName activity, boolean always, int userId, 14036 String opname) { 14037 // writer 14038 int callingUid = Binder.getCallingUid(); 14039 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 14040 if (filter.countActions() == 0) { 14041 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 14042 return; 14043 } 14044 synchronized (mPackages) { 14045 if (mContext.checkCallingOrSelfPermission( 14046 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 14047 != PackageManager.PERMISSION_GRANTED) { 14048 if (getUidTargetSdkVersionLockedLPr(callingUid) 14049 < Build.VERSION_CODES.FROYO) { 14050 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 14051 + callingUid); 14052 return; 14053 } 14054 mContext.enforceCallingOrSelfPermission( 14055 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14056 } 14057 14058 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 14059 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 14060 + userId + ":"); 14061 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14062 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 14063 scheduleWritePackageRestrictionsLocked(userId); 14064 } 14065 } 14066 14067 @Override 14068 public void replacePreferredActivity(IntentFilter filter, int match, 14069 ComponentName[] set, ComponentName activity, int userId) { 14070 if (filter.countActions() != 1) { 14071 throw new IllegalArgumentException( 14072 "replacePreferredActivity expects filter to have only 1 action."); 14073 } 14074 if (filter.countDataAuthorities() != 0 14075 || filter.countDataPaths() != 0 14076 || filter.countDataSchemes() > 1 14077 || filter.countDataTypes() != 0) { 14078 throw new IllegalArgumentException( 14079 "replacePreferredActivity expects filter to have no data authorities, " + 14080 "paths, or types; and at most one scheme."); 14081 } 14082 14083 final int callingUid = Binder.getCallingUid(); 14084 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 14085 synchronized (mPackages) { 14086 if (mContext.checkCallingOrSelfPermission( 14087 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 14088 != PackageManager.PERMISSION_GRANTED) { 14089 if (getUidTargetSdkVersionLockedLPr(callingUid) 14090 < Build.VERSION_CODES.FROYO) { 14091 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 14092 + Binder.getCallingUid()); 14093 return; 14094 } 14095 mContext.enforceCallingOrSelfPermission( 14096 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14097 } 14098 14099 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 14100 if (pir != null) { 14101 // Get all of the existing entries that exactly match this filter. 14102 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 14103 if (existing != null && existing.size() == 1) { 14104 PreferredActivity cur = existing.get(0); 14105 if (DEBUG_PREFERRED) { 14106 Slog.i(TAG, "Checking replace of preferred:"); 14107 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14108 if (!cur.mPref.mAlways) { 14109 Slog.i(TAG, " -- CUR; not mAlways!"); 14110 } else { 14111 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 14112 Slog.i(TAG, " -- CUR: mSet=" 14113 + Arrays.toString(cur.mPref.mSetComponents)); 14114 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 14115 Slog.i(TAG, " -- NEW: mMatch=" 14116 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 14117 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 14118 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 14119 } 14120 } 14121 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 14122 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 14123 && cur.mPref.sameSet(set)) { 14124 // Setting the preferred activity to what it happens to be already 14125 if (DEBUG_PREFERRED) { 14126 Slog.i(TAG, "Replacing with same preferred activity " 14127 + cur.mPref.mShortComponent + " for user " 14128 + userId + ":"); 14129 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14130 } 14131 return; 14132 } 14133 } 14134 14135 if (existing != null) { 14136 if (DEBUG_PREFERRED) { 14137 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 14138 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14139 } 14140 for (int i = 0; i < existing.size(); i++) { 14141 PreferredActivity pa = existing.get(i); 14142 if (DEBUG_PREFERRED) { 14143 Slog.i(TAG, "Removing existing preferred activity " 14144 + pa.mPref.mComponent + ":"); 14145 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 14146 } 14147 pir.removeFilter(pa); 14148 } 14149 } 14150 } 14151 addPreferredActivityInternal(filter, match, set, activity, true, userId, 14152 "Replacing preferred"); 14153 } 14154 } 14155 14156 @Override 14157 public void clearPackagePreferredActivities(String packageName) { 14158 final int uid = Binder.getCallingUid(); 14159 // writer 14160 synchronized (mPackages) { 14161 PackageParser.Package pkg = mPackages.get(packageName); 14162 if (pkg == null || pkg.applicationInfo.uid != uid) { 14163 if (mContext.checkCallingOrSelfPermission( 14164 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 14165 != PackageManager.PERMISSION_GRANTED) { 14166 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 14167 < Build.VERSION_CODES.FROYO) { 14168 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 14169 + Binder.getCallingUid()); 14170 return; 14171 } 14172 mContext.enforceCallingOrSelfPermission( 14173 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14174 } 14175 } 14176 14177 int user = UserHandle.getCallingUserId(); 14178 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 14179 scheduleWritePackageRestrictionsLocked(user); 14180 } 14181 } 14182 } 14183 14184 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 14185 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 14186 ArrayList<PreferredActivity> removed = null; 14187 boolean changed = false; 14188 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 14189 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 14190 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 14191 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 14192 continue; 14193 } 14194 Iterator<PreferredActivity> it = pir.filterIterator(); 14195 while (it.hasNext()) { 14196 PreferredActivity pa = it.next(); 14197 // Mark entry for removal only if it matches the package name 14198 // and the entry is of type "always". 14199 if (packageName == null || 14200 (pa.mPref.mComponent.getPackageName().equals(packageName) 14201 && pa.mPref.mAlways)) { 14202 if (removed == null) { 14203 removed = new ArrayList<PreferredActivity>(); 14204 } 14205 removed.add(pa); 14206 } 14207 } 14208 if (removed != null) { 14209 for (int j=0; j<removed.size(); j++) { 14210 PreferredActivity pa = removed.get(j); 14211 pir.removeFilter(pa); 14212 } 14213 changed = true; 14214 } 14215 } 14216 return changed; 14217 } 14218 14219 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 14220 private void clearIntentFilterVerificationsLPw(int userId) { 14221 final int packageCount = mPackages.size(); 14222 for (int i = 0; i < packageCount; i++) { 14223 PackageParser.Package pkg = mPackages.valueAt(i); 14224 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 14225 } 14226 } 14227 14228 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 14229 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 14230 if (userId == UserHandle.USER_ALL) { 14231 if (mSettings.removeIntentFilterVerificationLPw(packageName, 14232 sUserManager.getUserIds())) { 14233 for (int oneUserId : sUserManager.getUserIds()) { 14234 scheduleWritePackageRestrictionsLocked(oneUserId); 14235 } 14236 } 14237 } else { 14238 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 14239 scheduleWritePackageRestrictionsLocked(userId); 14240 } 14241 } 14242 } 14243 14244 void clearDefaultBrowserIfNeeded(String packageName) { 14245 for (int oneUserId : sUserManager.getUserIds()) { 14246 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 14247 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 14248 if (packageName.equals(defaultBrowserPackageName)) { 14249 setDefaultBrowserPackageName(null, oneUserId); 14250 } 14251 } 14252 } 14253 14254 @Override 14255 public void resetApplicationPreferences(int userId) { 14256 mContext.enforceCallingOrSelfPermission( 14257 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14258 // writer 14259 synchronized (mPackages) { 14260 final long identity = Binder.clearCallingIdentity(); 14261 try { 14262 clearPackagePreferredActivitiesLPw(null, userId); 14263 mSettings.applyDefaultPreferredAppsLPw(this, userId); 14264 // TODO: We have to reset the default SMS and Phone. This requires 14265 // significant refactoring to keep all default apps in the package 14266 // manager (cleaner but more work) or have the services provide 14267 // callbacks to the package manager to request a default app reset. 14268 applyFactoryDefaultBrowserLPw(userId); 14269 clearIntentFilterVerificationsLPw(userId); 14270 primeDomainVerificationsLPw(userId); 14271 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 14272 scheduleWritePackageRestrictionsLocked(userId); 14273 } finally { 14274 Binder.restoreCallingIdentity(identity); 14275 } 14276 } 14277 } 14278 14279 @Override 14280 public int getPreferredActivities(List<IntentFilter> outFilters, 14281 List<ComponentName> outActivities, String packageName) { 14282 14283 int num = 0; 14284 final int userId = UserHandle.getCallingUserId(); 14285 // reader 14286 synchronized (mPackages) { 14287 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 14288 if (pir != null) { 14289 final Iterator<PreferredActivity> it = pir.filterIterator(); 14290 while (it.hasNext()) { 14291 final PreferredActivity pa = it.next(); 14292 if (packageName == null 14293 || (pa.mPref.mComponent.getPackageName().equals(packageName) 14294 && pa.mPref.mAlways)) { 14295 if (outFilters != null) { 14296 outFilters.add(new IntentFilter(pa)); 14297 } 14298 if (outActivities != null) { 14299 outActivities.add(pa.mPref.mComponent); 14300 } 14301 } 14302 } 14303 } 14304 } 14305 14306 return num; 14307 } 14308 14309 @Override 14310 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 14311 int userId) { 14312 int callingUid = Binder.getCallingUid(); 14313 if (callingUid != Process.SYSTEM_UID) { 14314 throw new SecurityException( 14315 "addPersistentPreferredActivity can only be run by the system"); 14316 } 14317 if (filter.countActions() == 0) { 14318 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 14319 return; 14320 } 14321 synchronized (mPackages) { 14322 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 14323 " :"); 14324 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14325 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 14326 new PersistentPreferredActivity(filter, activity)); 14327 scheduleWritePackageRestrictionsLocked(userId); 14328 } 14329 } 14330 14331 @Override 14332 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 14333 int callingUid = Binder.getCallingUid(); 14334 if (callingUid != Process.SYSTEM_UID) { 14335 throw new SecurityException( 14336 "clearPackagePersistentPreferredActivities can only be run by the system"); 14337 } 14338 ArrayList<PersistentPreferredActivity> removed = null; 14339 boolean changed = false; 14340 synchronized (mPackages) { 14341 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 14342 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 14343 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 14344 .valueAt(i); 14345 if (userId != thisUserId) { 14346 continue; 14347 } 14348 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 14349 while (it.hasNext()) { 14350 PersistentPreferredActivity ppa = it.next(); 14351 // Mark entry for removal only if it matches the package name. 14352 if (ppa.mComponent.getPackageName().equals(packageName)) { 14353 if (removed == null) { 14354 removed = new ArrayList<PersistentPreferredActivity>(); 14355 } 14356 removed.add(ppa); 14357 } 14358 } 14359 if (removed != null) { 14360 for (int j=0; j<removed.size(); j++) { 14361 PersistentPreferredActivity ppa = removed.get(j); 14362 ppir.removeFilter(ppa); 14363 } 14364 changed = true; 14365 } 14366 } 14367 14368 if (changed) { 14369 scheduleWritePackageRestrictionsLocked(userId); 14370 } 14371 } 14372 } 14373 14374 /** 14375 * Common machinery for picking apart a restored XML blob and passing 14376 * it to a caller-supplied functor to be applied to the running system. 14377 */ 14378 private void restoreFromXml(XmlPullParser parser, int userId, 14379 String expectedStartTag, BlobXmlRestorer functor) 14380 throws IOException, XmlPullParserException { 14381 int type; 14382 while ((type = parser.next()) != XmlPullParser.START_TAG 14383 && type != XmlPullParser.END_DOCUMENT) { 14384 } 14385 if (type != XmlPullParser.START_TAG) { 14386 // oops didn't find a start tag?! 14387 if (DEBUG_BACKUP) { 14388 Slog.e(TAG, "Didn't find start tag during restore"); 14389 } 14390 return; 14391 } 14392 14393 // this is supposed to be TAG_PREFERRED_BACKUP 14394 if (!expectedStartTag.equals(parser.getName())) { 14395 if (DEBUG_BACKUP) { 14396 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 14397 } 14398 return; 14399 } 14400 14401 // skip interfering stuff, then we're aligned with the backing implementation 14402 while ((type = parser.next()) == XmlPullParser.TEXT) { } 14403 functor.apply(parser, userId); 14404 } 14405 14406 private interface BlobXmlRestorer { 14407 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 14408 } 14409 14410 /** 14411 * Non-Binder method, support for the backup/restore mechanism: write the 14412 * full set of preferred activities in its canonical XML format. Returns the 14413 * XML output as a byte array, or null if there is none. 14414 */ 14415 @Override 14416 public byte[] getPreferredActivityBackup(int userId) { 14417 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14418 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 14419 } 14420 14421 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14422 try { 14423 final XmlSerializer serializer = new FastXmlSerializer(); 14424 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14425 serializer.startDocument(null, true); 14426 serializer.startTag(null, TAG_PREFERRED_BACKUP); 14427 14428 synchronized (mPackages) { 14429 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 14430 } 14431 14432 serializer.endTag(null, TAG_PREFERRED_BACKUP); 14433 serializer.endDocument(); 14434 serializer.flush(); 14435 } catch (Exception e) { 14436 if (DEBUG_BACKUP) { 14437 Slog.e(TAG, "Unable to write preferred activities for backup", e); 14438 } 14439 return null; 14440 } 14441 14442 return dataStream.toByteArray(); 14443 } 14444 14445 @Override 14446 public void restorePreferredActivities(byte[] backup, int userId) { 14447 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14448 throw new SecurityException("Only the system may call restorePreferredActivities()"); 14449 } 14450 14451 try { 14452 final XmlPullParser parser = Xml.newPullParser(); 14453 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14454 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 14455 new BlobXmlRestorer() { 14456 @Override 14457 public void apply(XmlPullParser parser, int userId) 14458 throws XmlPullParserException, IOException { 14459 synchronized (mPackages) { 14460 mSettings.readPreferredActivitiesLPw(parser, userId); 14461 } 14462 } 14463 } ); 14464 } catch (Exception e) { 14465 if (DEBUG_BACKUP) { 14466 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 14467 } 14468 } 14469 } 14470 14471 /** 14472 * Non-Binder method, support for the backup/restore mechanism: write the 14473 * default browser (etc) settings in its canonical XML format. Returns the default 14474 * browser XML representation as a byte array, or null if there is none. 14475 */ 14476 @Override 14477 public byte[] getDefaultAppsBackup(int userId) { 14478 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14479 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 14480 } 14481 14482 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14483 try { 14484 final XmlSerializer serializer = new FastXmlSerializer(); 14485 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14486 serializer.startDocument(null, true); 14487 serializer.startTag(null, TAG_DEFAULT_APPS); 14488 14489 synchronized (mPackages) { 14490 mSettings.writeDefaultAppsLPr(serializer, userId); 14491 } 14492 14493 serializer.endTag(null, TAG_DEFAULT_APPS); 14494 serializer.endDocument(); 14495 serializer.flush(); 14496 } catch (Exception e) { 14497 if (DEBUG_BACKUP) { 14498 Slog.e(TAG, "Unable to write default apps for backup", e); 14499 } 14500 return null; 14501 } 14502 14503 return dataStream.toByteArray(); 14504 } 14505 14506 @Override 14507 public void restoreDefaultApps(byte[] backup, int userId) { 14508 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14509 throw new SecurityException("Only the system may call restoreDefaultApps()"); 14510 } 14511 14512 try { 14513 final XmlPullParser parser = Xml.newPullParser(); 14514 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14515 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 14516 new BlobXmlRestorer() { 14517 @Override 14518 public void apply(XmlPullParser parser, int userId) 14519 throws XmlPullParserException, IOException { 14520 synchronized (mPackages) { 14521 mSettings.readDefaultAppsLPw(parser, userId); 14522 } 14523 } 14524 } ); 14525 } catch (Exception e) { 14526 if (DEBUG_BACKUP) { 14527 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 14528 } 14529 } 14530 } 14531 14532 @Override 14533 public byte[] getIntentFilterVerificationBackup(int userId) { 14534 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14535 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 14536 } 14537 14538 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14539 try { 14540 final XmlSerializer serializer = new FastXmlSerializer(); 14541 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14542 serializer.startDocument(null, true); 14543 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 14544 14545 synchronized (mPackages) { 14546 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 14547 } 14548 14549 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 14550 serializer.endDocument(); 14551 serializer.flush(); 14552 } catch (Exception e) { 14553 if (DEBUG_BACKUP) { 14554 Slog.e(TAG, "Unable to write default apps for backup", e); 14555 } 14556 return null; 14557 } 14558 14559 return dataStream.toByteArray(); 14560 } 14561 14562 @Override 14563 public void restoreIntentFilterVerification(byte[] backup, int userId) { 14564 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14565 throw new SecurityException("Only the system may call restorePreferredActivities()"); 14566 } 14567 14568 try { 14569 final XmlPullParser parser = Xml.newPullParser(); 14570 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14571 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 14572 new BlobXmlRestorer() { 14573 @Override 14574 public void apply(XmlPullParser parser, int userId) 14575 throws XmlPullParserException, IOException { 14576 synchronized (mPackages) { 14577 mSettings.readAllDomainVerificationsLPr(parser, userId); 14578 mSettings.writeLPr(); 14579 } 14580 } 14581 } ); 14582 } catch (Exception e) { 14583 if (DEBUG_BACKUP) { 14584 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 14585 } 14586 } 14587 } 14588 14589 @Override 14590 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 14591 int sourceUserId, int targetUserId, int flags) { 14592 mContext.enforceCallingOrSelfPermission( 14593 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 14594 int callingUid = Binder.getCallingUid(); 14595 enforceOwnerRights(ownerPackage, callingUid); 14596 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 14597 if (intentFilter.countActions() == 0) { 14598 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 14599 return; 14600 } 14601 synchronized (mPackages) { 14602 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 14603 ownerPackage, targetUserId, flags); 14604 CrossProfileIntentResolver resolver = 14605 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 14606 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 14607 // We have all those whose filter is equal. Now checking if the rest is equal as well. 14608 if (existing != null) { 14609 int size = existing.size(); 14610 for (int i = 0; i < size; i++) { 14611 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 14612 return; 14613 } 14614 } 14615 } 14616 resolver.addFilter(newFilter); 14617 scheduleWritePackageRestrictionsLocked(sourceUserId); 14618 } 14619 } 14620 14621 @Override 14622 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 14623 mContext.enforceCallingOrSelfPermission( 14624 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 14625 int callingUid = Binder.getCallingUid(); 14626 enforceOwnerRights(ownerPackage, callingUid); 14627 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 14628 synchronized (mPackages) { 14629 CrossProfileIntentResolver resolver = 14630 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 14631 ArraySet<CrossProfileIntentFilter> set = 14632 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 14633 for (CrossProfileIntentFilter filter : set) { 14634 if (filter.getOwnerPackage().equals(ownerPackage)) { 14635 resolver.removeFilter(filter); 14636 } 14637 } 14638 scheduleWritePackageRestrictionsLocked(sourceUserId); 14639 } 14640 } 14641 14642 // Enforcing that callingUid is owning pkg on userId 14643 private void enforceOwnerRights(String pkg, int callingUid) { 14644 // The system owns everything. 14645 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 14646 return; 14647 } 14648 int callingUserId = UserHandle.getUserId(callingUid); 14649 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 14650 if (pi == null) { 14651 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 14652 + callingUserId); 14653 } 14654 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 14655 throw new SecurityException("Calling uid " + callingUid 14656 + " does not own package " + pkg); 14657 } 14658 } 14659 14660 @Override 14661 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 14662 Intent intent = new Intent(Intent.ACTION_MAIN); 14663 intent.addCategory(Intent.CATEGORY_HOME); 14664 14665 final int callingUserId = UserHandle.getCallingUserId(); 14666 List<ResolveInfo> list = queryIntentActivities(intent, null, 14667 PackageManager.GET_META_DATA, callingUserId); 14668 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 14669 true, false, false, callingUserId); 14670 14671 allHomeCandidates.clear(); 14672 if (list != null) { 14673 for (ResolveInfo ri : list) { 14674 allHomeCandidates.add(ri); 14675 } 14676 } 14677 return (preferred == null || preferred.activityInfo == null) 14678 ? null 14679 : new ComponentName(preferred.activityInfo.packageName, 14680 preferred.activityInfo.name); 14681 } 14682 14683 @Override 14684 public void setApplicationEnabledSetting(String appPackageName, 14685 int newState, int flags, int userId, String callingPackage) { 14686 if (!sUserManager.exists(userId)) return; 14687 if (callingPackage == null) { 14688 callingPackage = Integer.toString(Binder.getCallingUid()); 14689 } 14690 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 14691 } 14692 14693 @Override 14694 public void setComponentEnabledSetting(ComponentName componentName, 14695 int newState, int flags, int userId) { 14696 if (!sUserManager.exists(userId)) return; 14697 setEnabledSetting(componentName.getPackageName(), 14698 componentName.getClassName(), newState, flags, userId, null); 14699 } 14700 14701 private void setEnabledSetting(final String packageName, String className, int newState, 14702 final int flags, int userId, String callingPackage) { 14703 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 14704 || newState == COMPONENT_ENABLED_STATE_ENABLED 14705 || newState == COMPONENT_ENABLED_STATE_DISABLED 14706 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 14707 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 14708 throw new IllegalArgumentException("Invalid new component state: " 14709 + newState); 14710 } 14711 PackageSetting pkgSetting; 14712 final int uid = Binder.getCallingUid(); 14713 final int permission = mContext.checkCallingOrSelfPermission( 14714 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 14715 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 14716 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 14717 boolean sendNow = false; 14718 boolean isApp = (className == null); 14719 String componentName = isApp ? packageName : className; 14720 int packageUid = -1; 14721 ArrayList<String> components; 14722 14723 // writer 14724 synchronized (mPackages) { 14725 pkgSetting = mSettings.mPackages.get(packageName); 14726 if (pkgSetting == null) { 14727 if (className == null) { 14728 throw new IllegalArgumentException( 14729 "Unknown package: " + packageName); 14730 } 14731 throw new IllegalArgumentException( 14732 "Unknown component: " + packageName 14733 + "/" + className); 14734 } 14735 // Allow root and verify that userId is not being specified by a different user 14736 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 14737 throw new SecurityException( 14738 "Permission Denial: attempt to change component state from pid=" 14739 + Binder.getCallingPid() 14740 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 14741 } 14742 if (className == null) { 14743 // We're dealing with an application/package level state change 14744 if (pkgSetting.getEnabled(userId) == newState) { 14745 // Nothing to do 14746 return; 14747 } 14748 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 14749 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 14750 // Don't care about who enables an app. 14751 callingPackage = null; 14752 } 14753 pkgSetting.setEnabled(newState, userId, callingPackage); 14754 // pkgSetting.pkg.mSetEnabled = newState; 14755 } else { 14756 // We're dealing with a component level state change 14757 // First, verify that this is a valid class name. 14758 PackageParser.Package pkg = pkgSetting.pkg; 14759 if (pkg == null || !pkg.hasComponentClassName(className)) { 14760 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 14761 throw new IllegalArgumentException("Component class " + className 14762 + " does not exist in " + packageName); 14763 } else { 14764 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 14765 + className + " does not exist in " + packageName); 14766 } 14767 } 14768 switch (newState) { 14769 case COMPONENT_ENABLED_STATE_ENABLED: 14770 if (!pkgSetting.enableComponentLPw(className, userId)) { 14771 return; 14772 } 14773 break; 14774 case COMPONENT_ENABLED_STATE_DISABLED: 14775 if (!pkgSetting.disableComponentLPw(className, userId)) { 14776 return; 14777 } 14778 break; 14779 case COMPONENT_ENABLED_STATE_DEFAULT: 14780 if (!pkgSetting.restoreComponentLPw(className, userId)) { 14781 return; 14782 } 14783 break; 14784 default: 14785 Slog.e(TAG, "Invalid new component state: " + newState); 14786 return; 14787 } 14788 } 14789 scheduleWritePackageRestrictionsLocked(userId); 14790 components = mPendingBroadcasts.get(userId, packageName); 14791 final boolean newPackage = components == null; 14792 if (newPackage) { 14793 components = new ArrayList<String>(); 14794 } 14795 if (!components.contains(componentName)) { 14796 components.add(componentName); 14797 } 14798 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 14799 sendNow = true; 14800 // Purge entry from pending broadcast list if another one exists already 14801 // since we are sending one right away. 14802 mPendingBroadcasts.remove(userId, packageName); 14803 } else { 14804 if (newPackage) { 14805 mPendingBroadcasts.put(userId, packageName, components); 14806 } 14807 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 14808 // Schedule a message 14809 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 14810 } 14811 } 14812 } 14813 14814 long callingId = Binder.clearCallingIdentity(); 14815 try { 14816 if (sendNow) { 14817 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 14818 sendPackageChangedBroadcast(packageName, 14819 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 14820 } 14821 } finally { 14822 Binder.restoreCallingIdentity(callingId); 14823 } 14824 } 14825 14826 private void sendPackageChangedBroadcast(String packageName, 14827 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 14828 if (DEBUG_INSTALL) 14829 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 14830 + componentNames); 14831 Bundle extras = new Bundle(4); 14832 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 14833 String nameList[] = new String[componentNames.size()]; 14834 componentNames.toArray(nameList); 14835 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 14836 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 14837 extras.putInt(Intent.EXTRA_UID, packageUid); 14838 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 14839 new int[] {UserHandle.getUserId(packageUid)}); 14840 } 14841 14842 @Override 14843 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 14844 if (!sUserManager.exists(userId)) return; 14845 final int uid = Binder.getCallingUid(); 14846 final int permission = mContext.checkCallingOrSelfPermission( 14847 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 14848 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 14849 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 14850 // writer 14851 synchronized (mPackages) { 14852 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 14853 allowedByPermission, uid, userId)) { 14854 scheduleWritePackageRestrictionsLocked(userId); 14855 } 14856 } 14857 } 14858 14859 @Override 14860 public String getInstallerPackageName(String packageName) { 14861 // reader 14862 synchronized (mPackages) { 14863 return mSettings.getInstallerPackageNameLPr(packageName); 14864 } 14865 } 14866 14867 @Override 14868 public int getApplicationEnabledSetting(String packageName, int userId) { 14869 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 14870 int uid = Binder.getCallingUid(); 14871 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 14872 // reader 14873 synchronized (mPackages) { 14874 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 14875 } 14876 } 14877 14878 @Override 14879 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 14880 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 14881 int uid = Binder.getCallingUid(); 14882 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 14883 // reader 14884 synchronized (mPackages) { 14885 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 14886 } 14887 } 14888 14889 @Override 14890 public void enterSafeMode() { 14891 enforceSystemOrRoot("Only the system can request entering safe mode"); 14892 14893 if (!mSystemReady) { 14894 mSafeMode = true; 14895 } 14896 } 14897 14898 @Override 14899 public void systemReady() { 14900 mSystemReady = true; 14901 14902 // Read the compatibilty setting when the system is ready. 14903 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 14904 mContext.getContentResolver(), 14905 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 14906 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 14907 if (DEBUG_SETTINGS) { 14908 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 14909 } 14910 14911 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 14912 14913 synchronized (mPackages) { 14914 // Verify that all of the preferred activity components actually 14915 // exist. It is possible for applications to be updated and at 14916 // that point remove a previously declared activity component that 14917 // had been set as a preferred activity. We try to clean this up 14918 // the next time we encounter that preferred activity, but it is 14919 // possible for the user flow to never be able to return to that 14920 // situation so here we do a sanity check to make sure we haven't 14921 // left any junk around. 14922 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 14923 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 14924 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 14925 removed.clear(); 14926 for (PreferredActivity pa : pir.filterSet()) { 14927 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 14928 removed.add(pa); 14929 } 14930 } 14931 if (removed.size() > 0) { 14932 for (int r=0; r<removed.size(); r++) { 14933 PreferredActivity pa = removed.get(r); 14934 Slog.w(TAG, "Removing dangling preferred activity: " 14935 + pa.mPref.mComponent); 14936 pir.removeFilter(pa); 14937 } 14938 mSettings.writePackageRestrictionsLPr( 14939 mSettings.mPreferredActivities.keyAt(i)); 14940 } 14941 } 14942 14943 for (int userId : UserManagerService.getInstance().getUserIds()) { 14944 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 14945 grantPermissionsUserIds = ArrayUtils.appendInt( 14946 grantPermissionsUserIds, userId); 14947 } 14948 } 14949 } 14950 sUserManager.systemReady(); 14951 14952 // If we upgraded grant all default permissions before kicking off. 14953 for (int userId : grantPermissionsUserIds) { 14954 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 14955 } 14956 14957 // Kick off any messages waiting for system ready 14958 if (mPostSystemReadyMessages != null) { 14959 for (Message msg : mPostSystemReadyMessages) { 14960 msg.sendToTarget(); 14961 } 14962 mPostSystemReadyMessages = null; 14963 } 14964 14965 // Watch for external volumes that come and go over time 14966 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14967 storage.registerListener(mStorageListener); 14968 14969 mInstallerService.systemReady(); 14970 mPackageDexOptimizer.systemReady(); 14971 14972 MountServiceInternal mountServiceInternal = LocalServices.getService( 14973 MountServiceInternal.class); 14974 mountServiceInternal.addExternalStoragePolicy( 14975 new MountServiceInternal.ExternalStorageMountPolicy() { 14976 @Override 14977 public int getMountMode(int uid, String packageName) { 14978 if (Process.isIsolated(uid)) { 14979 return Zygote.MOUNT_EXTERNAL_NONE; 14980 } 14981 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 14982 return Zygote.MOUNT_EXTERNAL_DEFAULT; 14983 } 14984 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 14985 return Zygote.MOUNT_EXTERNAL_DEFAULT; 14986 } 14987 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 14988 return Zygote.MOUNT_EXTERNAL_READ; 14989 } 14990 return Zygote.MOUNT_EXTERNAL_WRITE; 14991 } 14992 14993 @Override 14994 public boolean hasExternalStorage(int uid, String packageName) { 14995 return true; 14996 } 14997 }); 14998 } 14999 15000 @Override 15001 public boolean isSafeMode() { 15002 return mSafeMode; 15003 } 15004 15005 @Override 15006 public boolean hasSystemUidErrors() { 15007 return mHasSystemUidErrors; 15008 } 15009 15010 static String arrayToString(int[] array) { 15011 StringBuffer buf = new StringBuffer(128); 15012 buf.append('['); 15013 if (array != null) { 15014 for (int i=0; i<array.length; i++) { 15015 if (i > 0) buf.append(", "); 15016 buf.append(array[i]); 15017 } 15018 } 15019 buf.append(']'); 15020 return buf.toString(); 15021 } 15022 15023 static class DumpState { 15024 public static final int DUMP_LIBS = 1 << 0; 15025 public static final int DUMP_FEATURES = 1 << 1; 15026 public static final int DUMP_RESOLVERS = 1 << 2; 15027 public static final int DUMP_PERMISSIONS = 1 << 3; 15028 public static final int DUMP_PACKAGES = 1 << 4; 15029 public static final int DUMP_SHARED_USERS = 1 << 5; 15030 public static final int DUMP_MESSAGES = 1 << 6; 15031 public static final int DUMP_PROVIDERS = 1 << 7; 15032 public static final int DUMP_VERIFIERS = 1 << 8; 15033 public static final int DUMP_PREFERRED = 1 << 9; 15034 public static final int DUMP_PREFERRED_XML = 1 << 10; 15035 public static final int DUMP_KEYSETS = 1 << 11; 15036 public static final int DUMP_VERSION = 1 << 12; 15037 public static final int DUMP_INSTALLS = 1 << 13; 15038 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14; 15039 public static final int DUMP_DOMAIN_PREFERRED = 1 << 15; 15040 15041 public static final int OPTION_SHOW_FILTERS = 1 << 0; 15042 15043 private int mTypes; 15044 15045 private int mOptions; 15046 15047 private boolean mTitlePrinted; 15048 15049 private SharedUserSetting mSharedUser; 15050 15051 public boolean isDumping(int type) { 15052 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 15053 return true; 15054 } 15055 15056 return (mTypes & type) != 0; 15057 } 15058 15059 public void setDump(int type) { 15060 mTypes |= type; 15061 } 15062 15063 public boolean isOptionEnabled(int option) { 15064 return (mOptions & option) != 0; 15065 } 15066 15067 public void setOptionEnabled(int option) { 15068 mOptions |= option; 15069 } 15070 15071 public boolean onTitlePrinted() { 15072 final boolean printed = mTitlePrinted; 15073 mTitlePrinted = true; 15074 return printed; 15075 } 15076 15077 public boolean getTitlePrinted() { 15078 return mTitlePrinted; 15079 } 15080 15081 public void setTitlePrinted(boolean enabled) { 15082 mTitlePrinted = enabled; 15083 } 15084 15085 public SharedUserSetting getSharedUser() { 15086 return mSharedUser; 15087 } 15088 15089 public void setSharedUser(SharedUserSetting user) { 15090 mSharedUser = user; 15091 } 15092 } 15093 15094 @Override 15095 public void onShellCommand(FileDescriptor in, FileDescriptor out, 15096 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 15097 (new PackageManagerShellCommand(this)).exec( 15098 this, in, out, err, args, resultReceiver); 15099 } 15100 15101 @Override 15102 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 15103 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 15104 != PackageManager.PERMISSION_GRANTED) { 15105 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 15106 + Binder.getCallingPid() 15107 + ", uid=" + Binder.getCallingUid() 15108 + " without permission " 15109 + android.Manifest.permission.DUMP); 15110 return; 15111 } 15112 15113 DumpState dumpState = new DumpState(); 15114 boolean fullPreferred = false; 15115 boolean checkin = false; 15116 15117 String packageName = null; 15118 ArraySet<String> permissionNames = null; 15119 15120 int opti = 0; 15121 while (opti < args.length) { 15122 String opt = args[opti]; 15123 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 15124 break; 15125 } 15126 opti++; 15127 15128 if ("-a".equals(opt)) { 15129 // Right now we only know how to print all. 15130 } else if ("-h".equals(opt)) { 15131 pw.println("Package manager dump options:"); 15132 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 15133 pw.println(" --checkin: dump for a checkin"); 15134 pw.println(" -f: print details of intent filters"); 15135 pw.println(" -h: print this help"); 15136 pw.println(" cmd may be one of:"); 15137 pw.println(" l[ibraries]: list known shared libraries"); 15138 pw.println(" f[ibraries]: list device features"); 15139 pw.println(" k[eysets]: print known keysets"); 15140 pw.println(" r[esolvers]: dump intent resolvers"); 15141 pw.println(" perm[issions]: dump permissions"); 15142 pw.println(" permission [name ...]: dump declaration and use of given permission"); 15143 pw.println(" pref[erred]: print preferred package settings"); 15144 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 15145 pw.println(" prov[iders]: dump content providers"); 15146 pw.println(" p[ackages]: dump installed packages"); 15147 pw.println(" s[hared-users]: dump shared user IDs"); 15148 pw.println(" m[essages]: print collected runtime messages"); 15149 pw.println(" v[erifiers]: print package verifier info"); 15150 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 15151 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 15152 pw.println(" version: print database version info"); 15153 pw.println(" write: write current settings now"); 15154 pw.println(" installs: details about install sessions"); 15155 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 15156 pw.println(" <package.name>: info about given package"); 15157 return; 15158 } else if ("--checkin".equals(opt)) { 15159 checkin = true; 15160 } else if ("-f".equals(opt)) { 15161 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 15162 } else { 15163 pw.println("Unknown argument: " + opt + "; use -h for help"); 15164 } 15165 } 15166 15167 // Is the caller requesting to dump a particular piece of data? 15168 if (opti < args.length) { 15169 String cmd = args[opti]; 15170 opti++; 15171 // Is this a package name? 15172 if ("android".equals(cmd) || cmd.contains(".")) { 15173 packageName = cmd; 15174 // When dumping a single package, we always dump all of its 15175 // filter information since the amount of data will be reasonable. 15176 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 15177 } else if ("check-permission".equals(cmd)) { 15178 if (opti >= args.length) { 15179 pw.println("Error: check-permission missing permission argument"); 15180 return; 15181 } 15182 String perm = args[opti]; 15183 opti++; 15184 if (opti >= args.length) { 15185 pw.println("Error: check-permission missing package argument"); 15186 return; 15187 } 15188 String pkg = args[opti]; 15189 opti++; 15190 int user = UserHandle.getUserId(Binder.getCallingUid()); 15191 if (opti < args.length) { 15192 try { 15193 user = Integer.parseInt(args[opti]); 15194 } catch (NumberFormatException e) { 15195 pw.println("Error: check-permission user argument is not a number: " 15196 + args[opti]); 15197 return; 15198 } 15199 } 15200 pw.println(checkPermission(perm, pkg, user)); 15201 return; 15202 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 15203 dumpState.setDump(DumpState.DUMP_LIBS); 15204 } else if ("f".equals(cmd) || "features".equals(cmd)) { 15205 dumpState.setDump(DumpState.DUMP_FEATURES); 15206 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 15207 dumpState.setDump(DumpState.DUMP_RESOLVERS); 15208 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 15209 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 15210 } else if ("permission".equals(cmd)) { 15211 if (opti >= args.length) { 15212 pw.println("Error: permission requires permission name"); 15213 return; 15214 } 15215 permissionNames = new ArraySet<>(); 15216 while (opti < args.length) { 15217 permissionNames.add(args[opti]); 15218 opti++; 15219 } 15220 dumpState.setDump(DumpState.DUMP_PERMISSIONS 15221 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 15222 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 15223 dumpState.setDump(DumpState.DUMP_PREFERRED); 15224 } else if ("preferred-xml".equals(cmd)) { 15225 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 15226 if (opti < args.length && "--full".equals(args[opti])) { 15227 fullPreferred = true; 15228 opti++; 15229 } 15230 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 15231 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 15232 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 15233 dumpState.setDump(DumpState.DUMP_PACKAGES); 15234 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 15235 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 15236 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 15237 dumpState.setDump(DumpState.DUMP_PROVIDERS); 15238 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 15239 dumpState.setDump(DumpState.DUMP_MESSAGES); 15240 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 15241 dumpState.setDump(DumpState.DUMP_VERIFIERS); 15242 } else if ("i".equals(cmd) || "ifv".equals(cmd) 15243 || "intent-filter-verifiers".equals(cmd)) { 15244 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 15245 } else if ("version".equals(cmd)) { 15246 dumpState.setDump(DumpState.DUMP_VERSION); 15247 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 15248 dumpState.setDump(DumpState.DUMP_KEYSETS); 15249 } else if ("installs".equals(cmd)) { 15250 dumpState.setDump(DumpState.DUMP_INSTALLS); 15251 } else if ("write".equals(cmd)) { 15252 synchronized (mPackages) { 15253 mSettings.writeLPr(); 15254 pw.println("Settings written."); 15255 return; 15256 } 15257 } 15258 } 15259 15260 if (checkin) { 15261 pw.println("vers,1"); 15262 } 15263 15264 // reader 15265 synchronized (mPackages) { 15266 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 15267 if (!checkin) { 15268 if (dumpState.onTitlePrinted()) 15269 pw.println(); 15270 pw.println("Database versions:"); 15271 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 15272 } 15273 } 15274 15275 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 15276 if (!checkin) { 15277 if (dumpState.onTitlePrinted()) 15278 pw.println(); 15279 pw.println("Verifiers:"); 15280 pw.print(" Required: "); 15281 pw.print(mRequiredVerifierPackage); 15282 pw.print(" (uid="); 15283 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 15284 pw.println(")"); 15285 } else if (mRequiredVerifierPackage != null) { 15286 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 15287 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 15288 } 15289 } 15290 15291 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 15292 packageName == null) { 15293 if (mIntentFilterVerifierComponent != null) { 15294 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 15295 if (!checkin) { 15296 if (dumpState.onTitlePrinted()) 15297 pw.println(); 15298 pw.println("Intent Filter Verifier:"); 15299 pw.print(" Using: "); 15300 pw.print(verifierPackageName); 15301 pw.print(" (uid="); 15302 pw.print(getPackageUid(verifierPackageName, 0)); 15303 pw.println(")"); 15304 } else if (verifierPackageName != null) { 15305 pw.print("ifv,"); pw.print(verifierPackageName); 15306 pw.print(","); pw.println(getPackageUid(verifierPackageName, 0)); 15307 } 15308 } else { 15309 pw.println(); 15310 pw.println("No Intent Filter Verifier available!"); 15311 } 15312 } 15313 15314 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 15315 boolean printedHeader = false; 15316 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 15317 while (it.hasNext()) { 15318 String name = it.next(); 15319 SharedLibraryEntry ent = mSharedLibraries.get(name); 15320 if (!checkin) { 15321 if (!printedHeader) { 15322 if (dumpState.onTitlePrinted()) 15323 pw.println(); 15324 pw.println("Libraries:"); 15325 printedHeader = true; 15326 } 15327 pw.print(" "); 15328 } else { 15329 pw.print("lib,"); 15330 } 15331 pw.print(name); 15332 if (!checkin) { 15333 pw.print(" -> "); 15334 } 15335 if (ent.path != null) { 15336 if (!checkin) { 15337 pw.print("(jar) "); 15338 pw.print(ent.path); 15339 } else { 15340 pw.print(",jar,"); 15341 pw.print(ent.path); 15342 } 15343 } else { 15344 if (!checkin) { 15345 pw.print("(apk) "); 15346 pw.print(ent.apk); 15347 } else { 15348 pw.print(",apk,"); 15349 pw.print(ent.apk); 15350 } 15351 } 15352 pw.println(); 15353 } 15354 } 15355 15356 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 15357 if (dumpState.onTitlePrinted()) 15358 pw.println(); 15359 if (!checkin) { 15360 pw.println("Features:"); 15361 } 15362 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 15363 while (it.hasNext()) { 15364 String name = it.next(); 15365 if (!checkin) { 15366 pw.print(" "); 15367 } else { 15368 pw.print("feat,"); 15369 } 15370 pw.println(name); 15371 } 15372 } 15373 15374 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 15375 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 15376 : "Activity Resolver Table:", " ", packageName, 15377 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15378 dumpState.setTitlePrinted(true); 15379 } 15380 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 15381 : "Receiver Resolver Table:", " ", packageName, 15382 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15383 dumpState.setTitlePrinted(true); 15384 } 15385 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 15386 : "Service Resolver Table:", " ", packageName, 15387 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15388 dumpState.setTitlePrinted(true); 15389 } 15390 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 15391 : "Provider Resolver Table:", " ", packageName, 15392 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15393 dumpState.setTitlePrinted(true); 15394 } 15395 } 15396 15397 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 15398 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15399 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15400 int user = mSettings.mPreferredActivities.keyAt(i); 15401 if (pir.dump(pw, 15402 dumpState.getTitlePrinted() 15403 ? "\nPreferred Activities User " + user + ":" 15404 : "Preferred Activities User " + user + ":", " ", 15405 packageName, true, false)) { 15406 dumpState.setTitlePrinted(true); 15407 } 15408 } 15409 } 15410 15411 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 15412 pw.flush(); 15413 FileOutputStream fout = new FileOutputStream(fd); 15414 BufferedOutputStream str = new BufferedOutputStream(fout); 15415 XmlSerializer serializer = new FastXmlSerializer(); 15416 try { 15417 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 15418 serializer.startDocument(null, true); 15419 serializer.setFeature( 15420 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 15421 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 15422 serializer.endDocument(); 15423 serializer.flush(); 15424 } catch (IllegalArgumentException e) { 15425 pw.println("Failed writing: " + e); 15426 } catch (IllegalStateException e) { 15427 pw.println("Failed writing: " + e); 15428 } catch (IOException e) { 15429 pw.println("Failed writing: " + e); 15430 } 15431 } 15432 15433 if (!checkin 15434 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 15435 && packageName == null) { 15436 pw.println(); 15437 int count = mSettings.mPackages.size(); 15438 if (count == 0) { 15439 pw.println("No applications!"); 15440 pw.println(); 15441 } else { 15442 final String prefix = " "; 15443 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 15444 if (allPackageSettings.size() == 0) { 15445 pw.println("No domain preferred apps!"); 15446 pw.println(); 15447 } else { 15448 pw.println("App verification status:"); 15449 pw.println(); 15450 count = 0; 15451 for (PackageSetting ps : allPackageSettings) { 15452 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 15453 if (ivi == null || ivi.getPackageName() == null) continue; 15454 pw.println(prefix + "Package: " + ivi.getPackageName()); 15455 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 15456 pw.println(prefix + "Status: " + ivi.getStatusString()); 15457 pw.println(); 15458 count++; 15459 } 15460 if (count == 0) { 15461 pw.println(prefix + "No app verification established."); 15462 pw.println(); 15463 } 15464 for (int userId : sUserManager.getUserIds()) { 15465 pw.println("App linkages for user " + userId + ":"); 15466 pw.println(); 15467 count = 0; 15468 for (PackageSetting ps : allPackageSettings) { 15469 final long status = ps.getDomainVerificationStatusForUser(userId); 15470 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 15471 continue; 15472 } 15473 pw.println(prefix + "Package: " + ps.name); 15474 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 15475 String statusStr = IntentFilterVerificationInfo. 15476 getStatusStringFromValue(status); 15477 pw.println(prefix + "Status: " + statusStr); 15478 pw.println(); 15479 count++; 15480 } 15481 if (count == 0) { 15482 pw.println(prefix + "No configured app linkages."); 15483 pw.println(); 15484 } 15485 } 15486 } 15487 } 15488 } 15489 15490 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 15491 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 15492 if (packageName == null && permissionNames == null) { 15493 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 15494 if (iperm == 0) { 15495 if (dumpState.onTitlePrinted()) 15496 pw.println(); 15497 pw.println("AppOp Permissions:"); 15498 } 15499 pw.print(" AppOp Permission "); 15500 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 15501 pw.println(":"); 15502 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 15503 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 15504 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 15505 } 15506 } 15507 } 15508 } 15509 15510 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 15511 boolean printedSomething = false; 15512 for (PackageParser.Provider p : mProviders.mProviders.values()) { 15513 if (packageName != null && !packageName.equals(p.info.packageName)) { 15514 continue; 15515 } 15516 if (!printedSomething) { 15517 if (dumpState.onTitlePrinted()) 15518 pw.println(); 15519 pw.println("Registered ContentProviders:"); 15520 printedSomething = true; 15521 } 15522 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 15523 pw.print(" "); pw.println(p.toString()); 15524 } 15525 printedSomething = false; 15526 for (Map.Entry<String, PackageParser.Provider> entry : 15527 mProvidersByAuthority.entrySet()) { 15528 PackageParser.Provider p = entry.getValue(); 15529 if (packageName != null && !packageName.equals(p.info.packageName)) { 15530 continue; 15531 } 15532 if (!printedSomething) { 15533 if (dumpState.onTitlePrinted()) 15534 pw.println(); 15535 pw.println("ContentProvider Authorities:"); 15536 printedSomething = true; 15537 } 15538 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 15539 pw.print(" "); pw.println(p.toString()); 15540 if (p.info != null && p.info.applicationInfo != null) { 15541 final String appInfo = p.info.applicationInfo.toString(); 15542 pw.print(" applicationInfo="); pw.println(appInfo); 15543 } 15544 } 15545 } 15546 15547 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 15548 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 15549 } 15550 15551 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 15552 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 15553 } 15554 15555 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 15556 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 15557 } 15558 15559 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 15560 // XXX should handle packageName != null by dumping only install data that 15561 // the given package is involved with. 15562 if (dumpState.onTitlePrinted()) pw.println(); 15563 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 15564 } 15565 15566 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 15567 if (dumpState.onTitlePrinted()) pw.println(); 15568 mSettings.dumpReadMessagesLPr(pw, dumpState); 15569 15570 pw.println(); 15571 pw.println("Package warning messages:"); 15572 BufferedReader in = null; 15573 String line = null; 15574 try { 15575 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 15576 while ((line = in.readLine()) != null) { 15577 if (line.contains("ignored: updated version")) continue; 15578 pw.println(line); 15579 } 15580 } catch (IOException ignored) { 15581 } finally { 15582 IoUtils.closeQuietly(in); 15583 } 15584 } 15585 15586 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 15587 BufferedReader in = null; 15588 String line = null; 15589 try { 15590 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 15591 while ((line = in.readLine()) != null) { 15592 if (line.contains("ignored: updated version")) continue; 15593 pw.print("msg,"); 15594 pw.println(line); 15595 } 15596 } catch (IOException ignored) { 15597 } finally { 15598 IoUtils.closeQuietly(in); 15599 } 15600 } 15601 } 15602 } 15603 15604 private String dumpDomainString(String packageName) { 15605 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName); 15606 List<IntentFilter> filters = getAllIntentFilters(packageName); 15607 15608 ArraySet<String> result = new ArraySet<>(); 15609 if (iviList.size() > 0) { 15610 for (IntentFilterVerificationInfo ivi : iviList) { 15611 for (String host : ivi.getDomains()) { 15612 result.add(host); 15613 } 15614 } 15615 } 15616 if (filters != null && filters.size() > 0) { 15617 for (IntentFilter filter : filters) { 15618 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 15619 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 15620 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 15621 result.addAll(filter.getHostsList()); 15622 } 15623 } 15624 } 15625 15626 StringBuilder sb = new StringBuilder(result.size() * 16); 15627 for (String domain : result) { 15628 if (sb.length() > 0) sb.append(" "); 15629 sb.append(domain); 15630 } 15631 return sb.toString(); 15632 } 15633 15634 // ------- apps on sdcard specific code ------- 15635 static final boolean DEBUG_SD_INSTALL = false; 15636 15637 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 15638 15639 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 15640 15641 private boolean mMediaMounted = false; 15642 15643 static String getEncryptKey() { 15644 try { 15645 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 15646 SD_ENCRYPTION_KEYSTORE_NAME); 15647 if (sdEncKey == null) { 15648 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 15649 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 15650 if (sdEncKey == null) { 15651 Slog.e(TAG, "Failed to create encryption keys"); 15652 return null; 15653 } 15654 } 15655 return sdEncKey; 15656 } catch (NoSuchAlgorithmException nsae) { 15657 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 15658 return null; 15659 } catch (IOException ioe) { 15660 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 15661 return null; 15662 } 15663 } 15664 15665 /* 15666 * Update media status on PackageManager. 15667 */ 15668 @Override 15669 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 15670 int callingUid = Binder.getCallingUid(); 15671 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15672 throw new SecurityException("Media status can only be updated by the system"); 15673 } 15674 // reader; this apparently protects mMediaMounted, but should probably 15675 // be a different lock in that case. 15676 synchronized (mPackages) { 15677 Log.i(TAG, "Updating external media status from " 15678 + (mMediaMounted ? "mounted" : "unmounted") + " to " 15679 + (mediaStatus ? "mounted" : "unmounted")); 15680 if (DEBUG_SD_INSTALL) 15681 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 15682 + ", mMediaMounted=" + mMediaMounted); 15683 if (mediaStatus == mMediaMounted) { 15684 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 15685 : 0, -1); 15686 mHandler.sendMessage(msg); 15687 return; 15688 } 15689 mMediaMounted = mediaStatus; 15690 } 15691 // Queue up an async operation since the package installation may take a 15692 // little while. 15693 mHandler.post(new Runnable() { 15694 public void run() { 15695 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 15696 } 15697 }); 15698 } 15699 15700 /** 15701 * Called by MountService when the initial ASECs to scan are available. 15702 * Should block until all the ASEC containers are finished being scanned. 15703 */ 15704 public void scanAvailableAsecs() { 15705 updateExternalMediaStatusInner(true, false, false); 15706 if (mShouldRestoreconData) { 15707 SELinuxMMAC.setRestoreconDone(); 15708 mShouldRestoreconData = false; 15709 } 15710 } 15711 15712 /* 15713 * Collect information of applications on external media, map them against 15714 * existing containers and update information based on current mount status. 15715 * Please note that we always have to report status if reportStatus has been 15716 * set to true especially when unloading packages. 15717 */ 15718 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 15719 boolean externalStorage) { 15720 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 15721 int[] uidArr = EmptyArray.INT; 15722 15723 final String[] list = PackageHelper.getSecureContainerList(); 15724 if (ArrayUtils.isEmpty(list)) { 15725 Log.i(TAG, "No secure containers found"); 15726 } else { 15727 // Process list of secure containers and categorize them 15728 // as active or stale based on their package internal state. 15729 15730 // reader 15731 synchronized (mPackages) { 15732 for (String cid : list) { 15733 // Leave stages untouched for now; installer service owns them 15734 if (PackageInstallerService.isStageName(cid)) continue; 15735 15736 if (DEBUG_SD_INSTALL) 15737 Log.i(TAG, "Processing container " + cid); 15738 String pkgName = getAsecPackageName(cid); 15739 if (pkgName == null) { 15740 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 15741 continue; 15742 } 15743 if (DEBUG_SD_INSTALL) 15744 Log.i(TAG, "Looking for pkg : " + pkgName); 15745 15746 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15747 if (ps == null) { 15748 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 15749 continue; 15750 } 15751 15752 /* 15753 * Skip packages that are not external if we're unmounting 15754 * external storage. 15755 */ 15756 if (externalStorage && !isMounted && !isExternal(ps)) { 15757 continue; 15758 } 15759 15760 final AsecInstallArgs args = new AsecInstallArgs(cid, 15761 getAppDexInstructionSets(ps), ps.isForwardLocked()); 15762 // The package status is changed only if the code path 15763 // matches between settings and the container id. 15764 if (ps.codePathString != null 15765 && ps.codePathString.startsWith(args.getCodePath())) { 15766 if (DEBUG_SD_INSTALL) { 15767 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 15768 + " at code path: " + ps.codePathString); 15769 } 15770 15771 // We do have a valid package installed on sdcard 15772 processCids.put(args, ps.codePathString); 15773 final int uid = ps.appId; 15774 if (uid != -1) { 15775 uidArr = ArrayUtils.appendInt(uidArr, uid); 15776 } 15777 } else { 15778 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 15779 + ps.codePathString); 15780 } 15781 } 15782 } 15783 15784 Arrays.sort(uidArr); 15785 } 15786 15787 // Process packages with valid entries. 15788 if (isMounted) { 15789 if (DEBUG_SD_INSTALL) 15790 Log.i(TAG, "Loading packages"); 15791 loadMediaPackages(processCids, uidArr, externalStorage); 15792 startCleaningPackages(); 15793 mInstallerService.onSecureContainersAvailable(); 15794 } else { 15795 if (DEBUG_SD_INSTALL) 15796 Log.i(TAG, "Unloading packages"); 15797 unloadMediaPackages(processCids, uidArr, reportStatus); 15798 } 15799 } 15800 15801 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15802 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 15803 final int size = infos.size(); 15804 final String[] packageNames = new String[size]; 15805 final int[] packageUids = new int[size]; 15806 for (int i = 0; i < size; i++) { 15807 final ApplicationInfo info = infos.get(i); 15808 packageNames[i] = info.packageName; 15809 packageUids[i] = info.uid; 15810 } 15811 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 15812 finishedReceiver); 15813 } 15814 15815 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15816 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 15817 sendResourcesChangedBroadcast(mediaStatus, replacing, 15818 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 15819 } 15820 15821 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15822 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 15823 int size = pkgList.length; 15824 if (size > 0) { 15825 // Send broadcasts here 15826 Bundle extras = new Bundle(); 15827 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 15828 if (uidArr != null) { 15829 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 15830 } 15831 if (replacing) { 15832 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 15833 } 15834 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 15835 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 15836 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 15837 } 15838 } 15839 15840 /* 15841 * Look at potentially valid container ids from processCids If package 15842 * information doesn't match the one on record or package scanning fails, 15843 * the cid is added to list of removeCids. We currently don't delete stale 15844 * containers. 15845 */ 15846 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 15847 boolean externalStorage) { 15848 ArrayList<String> pkgList = new ArrayList<String>(); 15849 Set<AsecInstallArgs> keys = processCids.keySet(); 15850 15851 for (AsecInstallArgs args : keys) { 15852 String codePath = processCids.get(args); 15853 if (DEBUG_SD_INSTALL) 15854 Log.i(TAG, "Loading container : " + args.cid); 15855 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15856 try { 15857 // Make sure there are no container errors first. 15858 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 15859 Slog.e(TAG, "Failed to mount cid : " + args.cid 15860 + " when installing from sdcard"); 15861 continue; 15862 } 15863 // Check code path here. 15864 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 15865 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 15866 + " does not match one in settings " + codePath); 15867 continue; 15868 } 15869 // Parse package 15870 int parseFlags = mDefParseFlags; 15871 if (args.isExternalAsec()) { 15872 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 15873 } 15874 if (args.isFwdLocked()) { 15875 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 15876 } 15877 15878 synchronized (mInstallLock) { 15879 PackageParser.Package pkg = null; 15880 try { 15881 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 15882 } catch (PackageManagerException e) { 15883 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 15884 } 15885 // Scan the package 15886 if (pkg != null) { 15887 /* 15888 * TODO why is the lock being held? doPostInstall is 15889 * called in other places without the lock. This needs 15890 * to be straightened out. 15891 */ 15892 // writer 15893 synchronized (mPackages) { 15894 retCode = PackageManager.INSTALL_SUCCEEDED; 15895 pkgList.add(pkg.packageName); 15896 // Post process args 15897 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 15898 pkg.applicationInfo.uid); 15899 } 15900 } else { 15901 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 15902 } 15903 } 15904 15905 } finally { 15906 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 15907 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 15908 } 15909 } 15910 } 15911 // writer 15912 synchronized (mPackages) { 15913 // If the platform SDK has changed since the last time we booted, 15914 // we need to re-grant app permission to catch any new ones that 15915 // appear. This is really a hack, and means that apps can in some 15916 // cases get permissions that the user didn't initially explicitly 15917 // allow... it would be nice to have some better way to handle 15918 // this situation. 15919 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 15920 : mSettings.getInternalVersion(); 15921 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 15922 : StorageManager.UUID_PRIVATE_INTERNAL; 15923 15924 int updateFlags = UPDATE_PERMISSIONS_ALL; 15925 if (ver.sdkVersion != mSdkVersion) { 15926 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 15927 + mSdkVersion + "; regranting permissions for external"); 15928 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 15929 } 15930 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 15931 15932 // Yay, everything is now upgraded 15933 ver.forceCurrent(); 15934 15935 // can downgrade to reader 15936 // Persist settings 15937 mSettings.writeLPr(); 15938 } 15939 // Send a broadcast to let everyone know we are done processing 15940 if (pkgList.size() > 0) { 15941 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 15942 } 15943 } 15944 15945 /* 15946 * Utility method to unload a list of specified containers 15947 */ 15948 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 15949 // Just unmount all valid containers. 15950 for (AsecInstallArgs arg : cidArgs) { 15951 synchronized (mInstallLock) { 15952 arg.doPostDeleteLI(false); 15953 } 15954 } 15955 } 15956 15957 /* 15958 * Unload packages mounted on external media. This involves deleting package 15959 * data from internal structures, sending broadcasts about diabled packages, 15960 * gc'ing to free up references, unmounting all secure containers 15961 * corresponding to packages on external media, and posting a 15962 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 15963 * that we always have to post this message if status has been requested no 15964 * matter what. 15965 */ 15966 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 15967 final boolean reportStatus) { 15968 if (DEBUG_SD_INSTALL) 15969 Log.i(TAG, "unloading media packages"); 15970 ArrayList<String> pkgList = new ArrayList<String>(); 15971 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 15972 final Set<AsecInstallArgs> keys = processCids.keySet(); 15973 for (AsecInstallArgs args : keys) { 15974 String pkgName = args.getPackageName(); 15975 if (DEBUG_SD_INSTALL) 15976 Log.i(TAG, "Trying to unload pkg : " + pkgName); 15977 // Delete package internally 15978 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 15979 synchronized (mInstallLock) { 15980 boolean res = deletePackageLI(pkgName, null, false, null, null, 15981 PackageManager.DELETE_KEEP_DATA, outInfo, false); 15982 if (res) { 15983 pkgList.add(pkgName); 15984 } else { 15985 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 15986 failedList.add(args); 15987 } 15988 } 15989 } 15990 15991 // reader 15992 synchronized (mPackages) { 15993 // We didn't update the settings after removing each package; 15994 // write them now for all packages. 15995 mSettings.writeLPr(); 15996 } 15997 15998 // We have to absolutely send UPDATED_MEDIA_STATUS only 15999 // after confirming that all the receivers processed the ordered 16000 // broadcast when packages get disabled, force a gc to clean things up. 16001 // and unload all the containers. 16002 if (pkgList.size() > 0) { 16003 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 16004 new IIntentReceiver.Stub() { 16005 public void performReceive(Intent intent, int resultCode, String data, 16006 Bundle extras, boolean ordered, boolean sticky, 16007 int sendingUser) throws RemoteException { 16008 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 16009 reportStatus ? 1 : 0, 1, keys); 16010 mHandler.sendMessage(msg); 16011 } 16012 }); 16013 } else { 16014 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 16015 keys); 16016 mHandler.sendMessage(msg); 16017 } 16018 } 16019 16020 private void loadPrivatePackages(final VolumeInfo vol) { 16021 mHandler.post(new Runnable() { 16022 @Override 16023 public void run() { 16024 loadPrivatePackagesInner(vol); 16025 } 16026 }); 16027 } 16028 16029 private void loadPrivatePackagesInner(VolumeInfo vol) { 16030 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 16031 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 16032 16033 final VersionInfo ver; 16034 final List<PackageSetting> packages; 16035 synchronized (mPackages) { 16036 ver = mSettings.findOrCreateVersion(vol.fsUuid); 16037 packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 16038 } 16039 16040 for (PackageSetting ps : packages) { 16041 synchronized (mInstallLock) { 16042 final PackageParser.Package pkg; 16043 try { 16044 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 16045 loaded.add(pkg.applicationInfo); 16046 } catch (PackageManagerException e) { 16047 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 16048 } 16049 16050 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 16051 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 16052 } 16053 } 16054 } 16055 16056 synchronized (mPackages) { 16057 int updateFlags = UPDATE_PERMISSIONS_ALL; 16058 if (ver.sdkVersion != mSdkVersion) { 16059 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 16060 + mSdkVersion + "; regranting permissions for " + vol.fsUuid); 16061 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 16062 } 16063 updatePermissionsLPw(null, null, vol.fsUuid, updateFlags); 16064 16065 // Yay, everything is now upgraded 16066 ver.forceCurrent(); 16067 16068 mSettings.writeLPr(); 16069 } 16070 16071 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 16072 sendResourcesChangedBroadcast(true, false, loaded, null); 16073 } 16074 16075 private void unloadPrivatePackages(final VolumeInfo vol) { 16076 mHandler.post(new Runnable() { 16077 @Override 16078 public void run() { 16079 unloadPrivatePackagesInner(vol); 16080 } 16081 }); 16082 } 16083 16084 private void unloadPrivatePackagesInner(VolumeInfo vol) { 16085 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 16086 synchronized (mInstallLock) { 16087 synchronized (mPackages) { 16088 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 16089 for (PackageSetting ps : packages) { 16090 if (ps.pkg == null) continue; 16091 16092 final ApplicationInfo info = ps.pkg.applicationInfo; 16093 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 16094 if (deletePackageLI(ps.name, null, false, null, null, 16095 PackageManager.DELETE_KEEP_DATA, outInfo, false)) { 16096 unloaded.add(info); 16097 } else { 16098 Slog.w(TAG, "Failed to unload " + ps.codePath); 16099 } 16100 } 16101 16102 mSettings.writeLPr(); 16103 } 16104 } 16105 16106 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 16107 sendResourcesChangedBroadcast(false, false, unloaded, null); 16108 } 16109 16110 /** 16111 * Examine all users present on given mounted volume, and destroy data 16112 * belonging to users that are no longer valid, or whose user ID has been 16113 * recycled. 16114 */ 16115 private void reconcileUsers(String volumeUuid) { 16116 final File[] files = FileUtils 16117 .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid)); 16118 for (File file : files) { 16119 if (!file.isDirectory()) continue; 16120 16121 final int userId; 16122 final UserInfo info; 16123 try { 16124 userId = Integer.parseInt(file.getName()); 16125 info = sUserManager.getUserInfo(userId); 16126 } catch (NumberFormatException e) { 16127 Slog.w(TAG, "Invalid user directory " + file); 16128 continue; 16129 } 16130 16131 boolean destroyUser = false; 16132 if (info == null) { 16133 logCriticalInfo(Log.WARN, "Destroying user directory " + file 16134 + " because no matching user was found"); 16135 destroyUser = true; 16136 } else { 16137 try { 16138 UserManagerService.enforceSerialNumber(file, info.serialNumber); 16139 } catch (IOException e) { 16140 logCriticalInfo(Log.WARN, "Destroying user directory " + file 16141 + " because we failed to enforce serial number: " + e); 16142 destroyUser = true; 16143 } 16144 } 16145 16146 if (destroyUser) { 16147 synchronized (mInstallLock) { 16148 mInstaller.removeUserDataDirs(volumeUuid, userId); 16149 } 16150 } 16151 } 16152 16153 final UserManager um = mContext.getSystemService(UserManager.class); 16154 for (UserInfo user : um.getUsers()) { 16155 final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id); 16156 if (userDir.exists()) continue; 16157 16158 try { 16159 UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id); 16160 UserManagerService.enforceSerialNumber(userDir, user.serialNumber); 16161 } catch (IOException e) { 16162 Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e); 16163 } 16164 } 16165 } 16166 16167 /** 16168 * Examine all apps present on given mounted volume, and destroy apps that 16169 * aren't expected, either due to uninstallation or reinstallation on 16170 * another volume. 16171 */ 16172 private void reconcileApps(String volumeUuid) { 16173 final File[] files = FileUtils 16174 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 16175 for (File file : files) { 16176 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 16177 && !PackageInstallerService.isStageName(file.getName()); 16178 if (!isPackage) { 16179 // Ignore entries which are not packages 16180 continue; 16181 } 16182 16183 boolean destroyApp = false; 16184 String packageName = null; 16185 try { 16186 final PackageLite pkg = PackageParser.parsePackageLite(file, 16187 PackageParser.PARSE_MUST_BE_APK); 16188 packageName = pkg.packageName; 16189 16190 synchronized (mPackages) { 16191 final PackageSetting ps = mSettings.mPackages.get(packageName); 16192 if (ps == null) { 16193 logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + " 16194 + volumeUuid + " because we found no install record"); 16195 destroyApp = true; 16196 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 16197 logCriticalInfo(Log.WARN, "Destroying " + packageName + " on " 16198 + volumeUuid + " because we expected it on " + ps.volumeUuid); 16199 destroyApp = true; 16200 } 16201 } 16202 16203 } catch (PackageParserException e) { 16204 logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e); 16205 destroyApp = true; 16206 } 16207 16208 if (destroyApp) { 16209 synchronized (mInstallLock) { 16210 if (packageName != null) { 16211 removeDataDirsLI(volumeUuid, packageName); 16212 } 16213 if (file.isDirectory()) { 16214 mInstaller.rmPackageDir(file.getAbsolutePath()); 16215 } else { 16216 file.delete(); 16217 } 16218 } 16219 } 16220 } 16221 } 16222 16223 private void unfreezePackage(String packageName) { 16224 synchronized (mPackages) { 16225 final PackageSetting ps = mSettings.mPackages.get(packageName); 16226 if (ps != null) { 16227 ps.frozen = false; 16228 } 16229 } 16230 } 16231 16232 @Override 16233 public int movePackage(final String packageName, final String volumeUuid) { 16234 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 16235 16236 final int moveId = mNextMoveId.getAndIncrement(); 16237 try { 16238 movePackageInternal(packageName, volumeUuid, moveId); 16239 } catch (PackageManagerException e) { 16240 Slog.w(TAG, "Failed to move " + packageName, e); 16241 mMoveCallbacks.notifyStatusChanged(moveId, 16242 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 16243 } 16244 return moveId; 16245 } 16246 16247 private void movePackageInternal(final String packageName, final String volumeUuid, 16248 final int moveId) throws PackageManagerException { 16249 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 16250 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16251 final PackageManager pm = mContext.getPackageManager(); 16252 16253 final boolean currentAsec; 16254 final String currentVolumeUuid; 16255 final File codeFile; 16256 final String installerPackageName; 16257 final String packageAbiOverride; 16258 final int appId; 16259 final String seinfo; 16260 final String label; 16261 16262 // reader 16263 synchronized (mPackages) { 16264 final PackageParser.Package pkg = mPackages.get(packageName); 16265 final PackageSetting ps = mSettings.mPackages.get(packageName); 16266 if (pkg == null || ps == null) { 16267 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 16268 } 16269 16270 if (pkg.applicationInfo.isSystemApp()) { 16271 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 16272 "Cannot move system application"); 16273 } 16274 16275 if (pkg.applicationInfo.isExternalAsec()) { 16276 currentAsec = true; 16277 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 16278 } else if (pkg.applicationInfo.isForwardLocked()) { 16279 currentAsec = true; 16280 currentVolumeUuid = "forward_locked"; 16281 } else { 16282 currentAsec = false; 16283 currentVolumeUuid = ps.volumeUuid; 16284 16285 final File probe = new File(pkg.codePath); 16286 final File probeOat = new File(probe, "oat"); 16287 if (!probe.isDirectory() || !probeOat.isDirectory()) { 16288 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16289 "Move only supported for modern cluster style installs"); 16290 } 16291 } 16292 16293 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 16294 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16295 "Package already moved to " + volumeUuid); 16296 } 16297 16298 if (ps.frozen) { 16299 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 16300 "Failed to move already frozen package"); 16301 } 16302 ps.frozen = true; 16303 16304 codeFile = new File(pkg.codePath); 16305 installerPackageName = ps.installerPackageName; 16306 packageAbiOverride = ps.cpuAbiOverrideString; 16307 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 16308 seinfo = pkg.applicationInfo.seinfo; 16309 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 16310 } 16311 16312 // Now that we're guarded by frozen state, kill app during move 16313 final long token = Binder.clearCallingIdentity(); 16314 try { 16315 killApplication(packageName, appId, "move pkg"); 16316 } finally { 16317 Binder.restoreCallingIdentity(token); 16318 } 16319 16320 final Bundle extras = new Bundle(); 16321 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 16322 extras.putString(Intent.EXTRA_TITLE, label); 16323 mMoveCallbacks.notifyCreated(moveId, extras); 16324 16325 int installFlags; 16326 final boolean moveCompleteApp; 16327 final File measurePath; 16328 16329 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 16330 installFlags = INSTALL_INTERNAL; 16331 moveCompleteApp = !currentAsec; 16332 measurePath = Environment.getDataAppDirectory(volumeUuid); 16333 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 16334 installFlags = INSTALL_EXTERNAL; 16335 moveCompleteApp = false; 16336 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 16337 } else { 16338 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 16339 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 16340 || !volume.isMountedWritable()) { 16341 unfreezePackage(packageName); 16342 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16343 "Move location not mounted private volume"); 16344 } 16345 16346 Preconditions.checkState(!currentAsec); 16347 16348 installFlags = INSTALL_INTERNAL; 16349 moveCompleteApp = true; 16350 measurePath = Environment.getDataAppDirectory(volumeUuid); 16351 } 16352 16353 final PackageStats stats = new PackageStats(null, -1); 16354 synchronized (mInstaller) { 16355 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 16356 unfreezePackage(packageName); 16357 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16358 "Failed to measure package size"); 16359 } 16360 } 16361 16362 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 16363 + stats.dataSize); 16364 16365 final long startFreeBytes = measurePath.getFreeSpace(); 16366 final long sizeBytes; 16367 if (moveCompleteApp) { 16368 sizeBytes = stats.codeSize + stats.dataSize; 16369 } else { 16370 sizeBytes = stats.codeSize; 16371 } 16372 16373 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 16374 unfreezePackage(packageName); 16375 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16376 "Not enough free space to move"); 16377 } 16378 16379 mMoveCallbacks.notifyStatusChanged(moveId, 10); 16380 16381 final CountDownLatch installedLatch = new CountDownLatch(1); 16382 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 16383 @Override 16384 public void onUserActionRequired(Intent intent) throws RemoteException { 16385 throw new IllegalStateException(); 16386 } 16387 16388 @Override 16389 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 16390 Bundle extras) throws RemoteException { 16391 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 16392 + PackageManager.installStatusToString(returnCode, msg)); 16393 16394 installedLatch.countDown(); 16395 16396 // Regardless of success or failure of the move operation, 16397 // always unfreeze the package 16398 unfreezePackage(packageName); 16399 16400 final int status = PackageManager.installStatusToPublicStatus(returnCode); 16401 switch (status) { 16402 case PackageInstaller.STATUS_SUCCESS: 16403 mMoveCallbacks.notifyStatusChanged(moveId, 16404 PackageManager.MOVE_SUCCEEDED); 16405 break; 16406 case PackageInstaller.STATUS_FAILURE_STORAGE: 16407 mMoveCallbacks.notifyStatusChanged(moveId, 16408 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 16409 break; 16410 default: 16411 mMoveCallbacks.notifyStatusChanged(moveId, 16412 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 16413 break; 16414 } 16415 } 16416 }; 16417 16418 final MoveInfo move; 16419 if (moveCompleteApp) { 16420 // Kick off a thread to report progress estimates 16421 new Thread() { 16422 @Override 16423 public void run() { 16424 while (true) { 16425 try { 16426 if (installedLatch.await(1, TimeUnit.SECONDS)) { 16427 break; 16428 } 16429 } catch (InterruptedException ignored) { 16430 } 16431 16432 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 16433 final int progress = 10 + (int) MathUtils.constrain( 16434 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 16435 mMoveCallbacks.notifyStatusChanged(moveId, progress); 16436 } 16437 } 16438 }.start(); 16439 16440 final String dataAppName = codeFile.getName(); 16441 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 16442 dataAppName, appId, seinfo); 16443 } else { 16444 move = null; 16445 } 16446 16447 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 16448 16449 final Message msg = mHandler.obtainMessage(INIT_COPY); 16450 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 16451 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 16452 installerPackageName, volumeUuid, null, user, packageAbiOverride, null); 16453 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 16454 msg.obj = params; 16455 16456 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 16457 System.identityHashCode(msg.obj)); 16458 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 16459 System.identityHashCode(msg.obj)); 16460 16461 mHandler.sendMessage(msg); 16462 } 16463 16464 @Override 16465 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 16466 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 16467 16468 final int realMoveId = mNextMoveId.getAndIncrement(); 16469 final Bundle extras = new Bundle(); 16470 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 16471 mMoveCallbacks.notifyCreated(realMoveId, extras); 16472 16473 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 16474 @Override 16475 public void onCreated(int moveId, Bundle extras) { 16476 // Ignored 16477 } 16478 16479 @Override 16480 public void onStatusChanged(int moveId, int status, long estMillis) { 16481 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 16482 } 16483 }; 16484 16485 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16486 storage.setPrimaryStorageUuid(volumeUuid, callback); 16487 return realMoveId; 16488 } 16489 16490 @Override 16491 public int getMoveStatus(int moveId) { 16492 mContext.enforceCallingOrSelfPermission( 16493 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16494 return mMoveCallbacks.mLastStatus.get(moveId); 16495 } 16496 16497 @Override 16498 public void registerMoveCallback(IPackageMoveObserver callback) { 16499 mContext.enforceCallingOrSelfPermission( 16500 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16501 mMoveCallbacks.register(callback); 16502 } 16503 16504 @Override 16505 public void unregisterMoveCallback(IPackageMoveObserver callback) { 16506 mContext.enforceCallingOrSelfPermission( 16507 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16508 mMoveCallbacks.unregister(callback); 16509 } 16510 16511 @Override 16512 public boolean setInstallLocation(int loc) { 16513 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 16514 null); 16515 if (getInstallLocation() == loc) { 16516 return true; 16517 } 16518 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 16519 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 16520 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 16521 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 16522 return true; 16523 } 16524 return false; 16525 } 16526 16527 @Override 16528 public int getInstallLocation() { 16529 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 16530 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 16531 PackageHelper.APP_INSTALL_AUTO); 16532 } 16533 16534 /** Called by UserManagerService */ 16535 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 16536 mDirtyUsers.remove(userHandle); 16537 mSettings.removeUserLPw(userHandle); 16538 mPendingBroadcasts.remove(userHandle); 16539 if (mInstaller != null) { 16540 // Technically, we shouldn't be doing this with the package lock 16541 // held. However, this is very rare, and there is already so much 16542 // other disk I/O going on, that we'll let it slide for now. 16543 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16544 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 16545 final String volumeUuid = vol.getFsUuid(); 16546 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 16547 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 16548 } 16549 } 16550 mUserNeedsBadging.delete(userHandle); 16551 removeUnusedPackagesLILPw(userManager, userHandle); 16552 } 16553 16554 /** 16555 * We're removing userHandle and would like to remove any downloaded packages 16556 * that are no longer in use by any other user. 16557 * @param userHandle the user being removed 16558 */ 16559 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 16560 final boolean DEBUG_CLEAN_APKS = false; 16561 int [] users = userManager.getUserIds(); 16562 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 16563 while (psit.hasNext()) { 16564 PackageSetting ps = psit.next(); 16565 if (ps.pkg == null) { 16566 continue; 16567 } 16568 final String packageName = ps.pkg.packageName; 16569 // Skip over if system app 16570 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 16571 continue; 16572 } 16573 if (DEBUG_CLEAN_APKS) { 16574 Slog.i(TAG, "Checking package " + packageName); 16575 } 16576 boolean keep = false; 16577 for (int i = 0; i < users.length; i++) { 16578 if (users[i] != userHandle && ps.getInstalled(users[i])) { 16579 keep = true; 16580 if (DEBUG_CLEAN_APKS) { 16581 Slog.i(TAG, " Keeping package " + packageName + " for user " 16582 + users[i]); 16583 } 16584 break; 16585 } 16586 } 16587 if (!keep) { 16588 if (DEBUG_CLEAN_APKS) { 16589 Slog.i(TAG, " Removing package " + packageName); 16590 } 16591 mHandler.post(new Runnable() { 16592 public void run() { 16593 deletePackageX(packageName, userHandle, 0); 16594 } //end run 16595 }); 16596 } 16597 } 16598 } 16599 16600 /** Called by UserManagerService */ 16601 void createNewUserLILPw(int userHandle) { 16602 if (mInstaller != null) { 16603 mInstaller.createUserConfig(userHandle); 16604 mSettings.createNewUserLILPw(this, mInstaller, userHandle); 16605 applyFactoryDefaultBrowserLPw(userHandle); 16606 primeDomainVerificationsLPw(userHandle); 16607 } 16608 } 16609 16610 void newUserCreated(final int userHandle) { 16611 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 16612 } 16613 16614 @Override 16615 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 16616 mContext.enforceCallingOrSelfPermission( 16617 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 16618 "Only package verification agents can read the verifier device identity"); 16619 16620 synchronized (mPackages) { 16621 return mSettings.getVerifierDeviceIdentityLPw(); 16622 } 16623 } 16624 16625 @Override 16626 public void setPermissionEnforced(String permission, boolean enforced) { 16627 // TODO: Now that we no longer change GID for storage, this should to away. 16628 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 16629 "setPermissionEnforced"); 16630 if (READ_EXTERNAL_STORAGE.equals(permission)) { 16631 synchronized (mPackages) { 16632 if (mSettings.mReadExternalStorageEnforced == null 16633 || mSettings.mReadExternalStorageEnforced != enforced) { 16634 mSettings.mReadExternalStorageEnforced = enforced; 16635 mSettings.writeLPr(); 16636 } 16637 } 16638 // kill any non-foreground processes so we restart them and 16639 // grant/revoke the GID. 16640 final IActivityManager am = ActivityManagerNative.getDefault(); 16641 if (am != null) { 16642 final long token = Binder.clearCallingIdentity(); 16643 try { 16644 am.killProcessesBelowForeground("setPermissionEnforcement"); 16645 } catch (RemoteException e) { 16646 } finally { 16647 Binder.restoreCallingIdentity(token); 16648 } 16649 } 16650 } else { 16651 throw new IllegalArgumentException("No selective enforcement for " + permission); 16652 } 16653 } 16654 16655 @Override 16656 @Deprecated 16657 public boolean isPermissionEnforced(String permission) { 16658 return true; 16659 } 16660 16661 @Override 16662 public boolean isStorageLow() { 16663 final long token = Binder.clearCallingIdentity(); 16664 try { 16665 final DeviceStorageMonitorInternal 16666 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 16667 if (dsm != null) { 16668 return dsm.isMemoryLow(); 16669 } else { 16670 return false; 16671 } 16672 } finally { 16673 Binder.restoreCallingIdentity(token); 16674 } 16675 } 16676 16677 @Override 16678 public IPackageInstaller getPackageInstaller() { 16679 return mInstallerService; 16680 } 16681 16682 private boolean userNeedsBadging(int userId) { 16683 int index = mUserNeedsBadging.indexOfKey(userId); 16684 if (index < 0) { 16685 final UserInfo userInfo; 16686 final long token = Binder.clearCallingIdentity(); 16687 try { 16688 userInfo = sUserManager.getUserInfo(userId); 16689 } finally { 16690 Binder.restoreCallingIdentity(token); 16691 } 16692 final boolean b; 16693 if (userInfo != null && userInfo.isManagedProfile()) { 16694 b = true; 16695 } else { 16696 b = false; 16697 } 16698 mUserNeedsBadging.put(userId, b); 16699 return b; 16700 } 16701 return mUserNeedsBadging.valueAt(index); 16702 } 16703 16704 @Override 16705 public KeySet getKeySetByAlias(String packageName, String alias) { 16706 if (packageName == null || alias == null) { 16707 return null; 16708 } 16709 synchronized(mPackages) { 16710 final PackageParser.Package pkg = mPackages.get(packageName); 16711 if (pkg == null) { 16712 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16713 throw new IllegalArgumentException("Unknown package: " + packageName); 16714 } 16715 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16716 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 16717 } 16718 } 16719 16720 @Override 16721 public KeySet getSigningKeySet(String packageName) { 16722 if (packageName == null) { 16723 return null; 16724 } 16725 synchronized(mPackages) { 16726 final PackageParser.Package pkg = mPackages.get(packageName); 16727 if (pkg == null) { 16728 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16729 throw new IllegalArgumentException("Unknown package: " + packageName); 16730 } 16731 if (pkg.applicationInfo.uid != Binder.getCallingUid() 16732 && Process.SYSTEM_UID != Binder.getCallingUid()) { 16733 throw new SecurityException("May not access signing KeySet of other apps."); 16734 } 16735 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16736 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 16737 } 16738 } 16739 16740 @Override 16741 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 16742 if (packageName == null || ks == null) { 16743 return false; 16744 } 16745 synchronized(mPackages) { 16746 final PackageParser.Package pkg = mPackages.get(packageName); 16747 if (pkg == null) { 16748 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16749 throw new IllegalArgumentException("Unknown package: " + packageName); 16750 } 16751 IBinder ksh = ks.getToken(); 16752 if (ksh instanceof KeySetHandle) { 16753 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16754 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 16755 } 16756 return false; 16757 } 16758 } 16759 16760 @Override 16761 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 16762 if (packageName == null || ks == null) { 16763 return false; 16764 } 16765 synchronized(mPackages) { 16766 final PackageParser.Package pkg = mPackages.get(packageName); 16767 if (pkg == null) { 16768 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16769 throw new IllegalArgumentException("Unknown package: " + packageName); 16770 } 16771 IBinder ksh = ks.getToken(); 16772 if (ksh instanceof KeySetHandle) { 16773 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16774 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 16775 } 16776 return false; 16777 } 16778 } 16779 16780 public void getUsageStatsIfNoPackageUsageInfo() { 16781 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 16782 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 16783 if (usm == null) { 16784 throw new IllegalStateException("UsageStatsManager must be initialized"); 16785 } 16786 long now = System.currentTimeMillis(); 16787 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 16788 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 16789 String packageName = entry.getKey(); 16790 PackageParser.Package pkg = mPackages.get(packageName); 16791 if (pkg == null) { 16792 continue; 16793 } 16794 UsageStats usage = entry.getValue(); 16795 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 16796 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 16797 } 16798 } 16799 } 16800 16801 /** 16802 * Check and throw if the given before/after packages would be considered a 16803 * downgrade. 16804 */ 16805 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 16806 throws PackageManagerException { 16807 if (after.versionCode < before.mVersionCode) { 16808 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16809 "Update version code " + after.versionCode + " is older than current " 16810 + before.mVersionCode); 16811 } else if (after.versionCode == before.mVersionCode) { 16812 if (after.baseRevisionCode < before.baseRevisionCode) { 16813 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16814 "Update base revision code " + after.baseRevisionCode 16815 + " is older than current " + before.baseRevisionCode); 16816 } 16817 16818 if (!ArrayUtils.isEmpty(after.splitNames)) { 16819 for (int i = 0; i < after.splitNames.length; i++) { 16820 final String splitName = after.splitNames[i]; 16821 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 16822 if (j != -1) { 16823 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 16824 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16825 "Update split " + splitName + " revision code " 16826 + after.splitRevisionCodes[i] + " is older than current " 16827 + before.splitRevisionCodes[j]); 16828 } 16829 } 16830 } 16831 } 16832 } 16833 } 16834 16835 private static class MoveCallbacks extends Handler { 16836 private static final int MSG_CREATED = 1; 16837 private static final int MSG_STATUS_CHANGED = 2; 16838 16839 private final RemoteCallbackList<IPackageMoveObserver> 16840 mCallbacks = new RemoteCallbackList<>(); 16841 16842 private final SparseIntArray mLastStatus = new SparseIntArray(); 16843 16844 public MoveCallbacks(Looper looper) { 16845 super(looper); 16846 } 16847 16848 public void register(IPackageMoveObserver callback) { 16849 mCallbacks.register(callback); 16850 } 16851 16852 public void unregister(IPackageMoveObserver callback) { 16853 mCallbacks.unregister(callback); 16854 } 16855 16856 @Override 16857 public void handleMessage(Message msg) { 16858 final SomeArgs args = (SomeArgs) msg.obj; 16859 final int n = mCallbacks.beginBroadcast(); 16860 for (int i = 0; i < n; i++) { 16861 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 16862 try { 16863 invokeCallback(callback, msg.what, args); 16864 } catch (RemoteException ignored) { 16865 } 16866 } 16867 mCallbacks.finishBroadcast(); 16868 args.recycle(); 16869 } 16870 16871 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 16872 throws RemoteException { 16873 switch (what) { 16874 case MSG_CREATED: { 16875 callback.onCreated(args.argi1, (Bundle) args.arg2); 16876 break; 16877 } 16878 case MSG_STATUS_CHANGED: { 16879 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 16880 break; 16881 } 16882 } 16883 } 16884 16885 private void notifyCreated(int moveId, Bundle extras) { 16886 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 16887 16888 final SomeArgs args = SomeArgs.obtain(); 16889 args.argi1 = moveId; 16890 args.arg2 = extras; 16891 obtainMessage(MSG_CREATED, args).sendToTarget(); 16892 } 16893 16894 private void notifyStatusChanged(int moveId, int status) { 16895 notifyStatusChanged(moveId, status, -1); 16896 } 16897 16898 private void notifyStatusChanged(int moveId, int status, long estMillis) { 16899 Slog.v(TAG, "Move " + moveId + " status " + status); 16900 16901 final SomeArgs args = SomeArgs.obtain(); 16902 args.argi1 = moveId; 16903 args.argi2 = status; 16904 args.arg3 = estMillis; 16905 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 16906 16907 synchronized (mLastStatus) { 16908 mLastStatus.put(moveId, status); 16909 } 16910 } 16911 } 16912 16913 private final class OnPermissionChangeListeners extends Handler { 16914 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 16915 16916 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 16917 new RemoteCallbackList<>(); 16918 16919 public OnPermissionChangeListeners(Looper looper) { 16920 super(looper); 16921 } 16922 16923 @Override 16924 public void handleMessage(Message msg) { 16925 switch (msg.what) { 16926 case MSG_ON_PERMISSIONS_CHANGED: { 16927 final int uid = msg.arg1; 16928 handleOnPermissionsChanged(uid); 16929 } break; 16930 } 16931 } 16932 16933 public void addListenerLocked(IOnPermissionsChangeListener listener) { 16934 mPermissionListeners.register(listener); 16935 16936 } 16937 16938 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 16939 mPermissionListeners.unregister(listener); 16940 } 16941 16942 public void onPermissionsChanged(int uid) { 16943 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 16944 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 16945 } 16946 } 16947 16948 private void handleOnPermissionsChanged(int uid) { 16949 final int count = mPermissionListeners.beginBroadcast(); 16950 try { 16951 for (int i = 0; i < count; i++) { 16952 IOnPermissionsChangeListener callback = mPermissionListeners 16953 .getBroadcastItem(i); 16954 try { 16955 callback.onPermissionsChanged(uid); 16956 } catch (RemoteException e) { 16957 Log.e(TAG, "Permission listener is dead", e); 16958 } 16959 } 16960 } finally { 16961 mPermissionListeners.finishBroadcast(); 16962 } 16963 } 16964 } 16965 16966 private class PackageManagerInternalImpl extends PackageManagerInternal { 16967 @Override 16968 public void setLocationPackagesProvider(PackagesProvider provider) { 16969 synchronized (mPackages) { 16970 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 16971 } 16972 } 16973 16974 @Override 16975 public void setImePackagesProvider(PackagesProvider provider) { 16976 synchronized (mPackages) { 16977 mDefaultPermissionPolicy.setImePackagesProviderLPr(provider); 16978 } 16979 } 16980 16981 @Override 16982 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 16983 synchronized (mPackages) { 16984 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 16985 } 16986 } 16987 16988 @Override 16989 public void setSmsAppPackagesProvider(PackagesProvider provider) { 16990 synchronized (mPackages) { 16991 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 16992 } 16993 } 16994 16995 @Override 16996 public void setDialerAppPackagesProvider(PackagesProvider provider) { 16997 synchronized (mPackages) { 16998 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 16999 } 17000 } 17001 17002 @Override 17003 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 17004 synchronized (mPackages) { 17005 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 17006 } 17007 } 17008 17009 @Override 17010 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 17011 synchronized (mPackages) { 17012 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 17013 } 17014 } 17015 17016 @Override 17017 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 17018 synchronized (mPackages) { 17019 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 17020 packageName, userId); 17021 } 17022 } 17023 17024 @Override 17025 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 17026 synchronized (mPackages) { 17027 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 17028 packageName, userId); 17029 } 17030 } 17031 @Override 17032 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 17033 synchronized (mPackages) { 17034 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 17035 packageName, userId); 17036 } 17037 } 17038 } 17039 17040 @Override 17041 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 17042 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 17043 synchronized (mPackages) { 17044 final long identity = Binder.clearCallingIdentity(); 17045 try { 17046 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 17047 packageNames, userId); 17048 } finally { 17049 Binder.restoreCallingIdentity(identity); 17050 } 17051 } 17052 } 17053 17054 private static void enforceSystemOrPhoneCaller(String tag) { 17055 int callingUid = Binder.getCallingUid(); 17056 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 17057 throw new SecurityException( 17058 "Cannot call " + tag + " from UID " + callingUid); 17059 } 17060 } 17061} 17062