PackageManagerService.java revision 53f35f4a20f69a61b83b88b666e85277d07e9de0
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.GRANT_REVOKE_PERMISSIONS; 20import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 26import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 27import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 28import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 29import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 30import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 31import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 32import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 33import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 34import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 35import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 36import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 37import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 38import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 39import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 40import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 41import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 42import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 43import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 44import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 45import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 46import static android.content.pm.PackageManager.INSTALL_INTERNAL; 47import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 48import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 49import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 50import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 51import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 52import static android.content.pm.PackageManager.MOVE_EXTERNAL_MEDIA; 53import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 54import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 55import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 56import static android.content.pm.PackageManager.MOVE_INTERNAL; 57import static android.content.pm.PackageParser.isApkFile; 58import static android.os.Process.PACKAGE_INFO_GID; 59import static android.os.Process.SYSTEM_UID; 60import static android.system.OsConstants.O_CREAT; 61import static android.system.OsConstants.O_RDWR; 62import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 63import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER; 64import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 65import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 66import static com.android.internal.util.ArrayUtils.appendInt; 67import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 68import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 69import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 70import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 71import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 72 73import android.Manifest; 74import org.xmlpull.v1.XmlPullParser; 75import android.app.ActivityManager; 76import android.app.ActivityManagerNative; 77import android.app.AppGlobals; 78import android.app.IActivityManager; 79import android.app.admin.IDevicePolicyManager; 80import android.app.backup.IBackupManager; 81import android.app.usage.UsageStats; 82import android.app.usage.UsageStatsManager; 83import android.content.BroadcastReceiver; 84import android.content.ComponentName; 85import android.content.Context; 86import android.content.IIntentReceiver; 87import android.content.Intent; 88import android.content.IntentFilter; 89import android.content.IntentSender; 90import android.content.IntentSender.SendIntentException; 91import android.content.ServiceConnection; 92import android.content.pm.ActivityInfo; 93import android.content.pm.ApplicationInfo; 94import android.content.pm.FeatureInfo; 95import android.content.pm.IPackageDataObserver; 96import android.content.pm.IPackageDeleteObserver; 97import android.content.pm.IPackageDeleteObserver2; 98import android.content.pm.IPackageInstallObserver2; 99import android.content.pm.IPackageInstaller; 100import android.content.pm.IPackageManager; 101import android.content.pm.IPackageMoveObserver; 102import android.content.pm.IPackageStatsObserver; 103import android.content.pm.InstrumentationInfo; 104import android.content.pm.IntentFilterVerificationInfo; 105import android.content.pm.KeySet; 106import android.content.pm.ManifestDigest; 107import android.content.pm.PackageCleanItem; 108import android.content.pm.PackageInfo; 109import android.content.pm.PackageInfoLite; 110import android.content.pm.PackageInstaller; 111import android.content.pm.PackageManager; 112import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 113import android.content.pm.PackageParser; 114import android.content.pm.PackageParser.ActivityIntentInfo; 115import android.content.pm.PackageParser.PackageLite; 116import android.content.pm.PackageParser.PackageParserException; 117import android.content.pm.PackageStats; 118import android.content.pm.PackageUserState; 119import android.content.pm.ParceledListSlice; 120import android.content.pm.PermissionGroupInfo; 121import android.content.pm.PermissionInfo; 122import android.content.pm.ProviderInfo; 123import android.content.pm.ResolveInfo; 124import android.content.pm.ServiceInfo; 125import android.content.pm.Signature; 126import android.content.pm.UserInfo; 127import android.content.pm.VerificationParams; 128import android.content.pm.VerifierDeviceIdentity; 129import android.content.pm.VerifierInfo; 130import android.content.res.Resources; 131import android.hardware.display.DisplayManager; 132import android.net.Uri; 133import android.os.Binder; 134import android.os.Build; 135import android.os.Bundle; 136import android.os.Debug; 137import android.os.Environment; 138import android.os.Environment.UserEnvironment; 139import android.os.FileUtils; 140import android.os.Handler; 141import android.os.IBinder; 142import android.os.Looper; 143import android.os.Message; 144import android.os.Parcel; 145import android.os.ParcelFileDescriptor; 146import android.os.Process; 147import android.os.RemoteException; 148import android.os.SELinux; 149import android.os.ServiceManager; 150import android.os.SystemClock; 151import android.os.SystemProperties; 152import android.os.UserHandle; 153import android.os.UserManager; 154import android.os.storage.IMountService; 155import android.os.storage.StorageEventListener; 156import android.os.storage.StorageManager; 157import android.os.storage.VolumeInfo; 158import android.security.KeyStore; 159import android.security.SystemKeyStore; 160import android.system.ErrnoException; 161import android.system.Os; 162import android.system.StructStat; 163import android.text.TextUtils; 164import android.text.format.DateUtils; 165import android.util.ArrayMap; 166import android.util.ArraySet; 167import android.util.AtomicFile; 168import android.util.DisplayMetrics; 169import android.util.EventLog; 170import android.util.ExceptionUtils; 171import android.util.Log; 172import android.util.LogPrinter; 173import android.util.PrintStreamPrinter; 174import android.util.Slog; 175import android.util.SparseArray; 176import android.util.SparseBooleanArray; 177import android.util.Xml; 178import android.view.Display; 179 180import dalvik.system.DexFile; 181import dalvik.system.VMRuntime; 182 183import libcore.io.IoUtils; 184import libcore.util.EmptyArray; 185 186import com.android.internal.R; 187import com.android.internal.app.IMediaContainerService; 188import com.android.internal.app.ResolverActivity; 189import com.android.internal.content.NativeLibraryHelper; 190import com.android.internal.content.PackageHelper; 191import com.android.internal.os.IParcelFileDescriptorFactory; 192import com.android.internal.util.ArrayUtils; 193import com.android.internal.util.FastPrintWriter; 194import com.android.internal.util.FastXmlSerializer; 195import com.android.internal.util.IndentingPrintWriter; 196import com.android.server.EventLogTags; 197import com.android.server.IntentResolver; 198import com.android.server.LocalServices; 199import com.android.server.ServiceThread; 200import com.android.server.SystemConfig; 201import com.android.server.Watchdog; 202import com.android.server.pm.Settings.DatabaseVersion; 203import com.android.server.storage.DeviceStorageMonitorInternal; 204 205import org.xmlpull.v1.XmlSerializer; 206 207import java.io.BufferedInputStream; 208import java.io.BufferedOutputStream; 209import java.io.BufferedReader; 210import java.io.ByteArrayInputStream; 211import java.io.ByteArrayOutputStream; 212import java.io.File; 213import java.io.FileDescriptor; 214import java.io.FileNotFoundException; 215import java.io.FileOutputStream; 216import java.io.FileReader; 217import java.io.FilenameFilter; 218import java.io.IOException; 219import java.io.InputStream; 220import java.io.PrintWriter; 221import java.nio.charset.StandardCharsets; 222import java.security.NoSuchAlgorithmException; 223import java.security.PublicKey; 224import java.security.cert.CertificateEncodingException; 225import java.security.cert.CertificateException; 226import java.text.SimpleDateFormat; 227import java.util.ArrayList; 228import java.util.Arrays; 229import java.util.Collection; 230import java.util.Collections; 231import java.util.Comparator; 232import java.util.Date; 233import java.util.Iterator; 234import java.util.List; 235import java.util.Map; 236import java.util.Objects; 237import java.util.Set; 238import java.util.concurrent.atomic.AtomicBoolean; 239import java.util.concurrent.atomic.AtomicLong; 240 241/** 242 * Keep track of all those .apks everywhere. 243 * 244 * This is very central to the platform's security; please run the unit 245 * tests whenever making modifications here: 246 * 247mmm frameworks/base/tests/AndroidTests 248adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 249adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 250 * 251 * {@hide} 252 */ 253public class PackageManagerService extends IPackageManager.Stub { 254 static final String TAG = "PackageManager"; 255 static final boolean DEBUG_SETTINGS = false; 256 static final boolean DEBUG_PREFERRED = false; 257 static final boolean DEBUG_UPGRADE = false; 258 private static final boolean DEBUG_BACKUP = true; 259 private static final boolean DEBUG_INSTALL = false; 260 private static final boolean DEBUG_REMOVE = false; 261 private static final boolean DEBUG_BROADCASTS = false; 262 private static final boolean DEBUG_SHOW_INFO = false; 263 private static final boolean DEBUG_PACKAGE_INFO = false; 264 private static final boolean DEBUG_INTENT_MATCHING = false; 265 private static final boolean DEBUG_PACKAGE_SCANNING = false; 266 private static final boolean DEBUG_VERIFY = false; 267 private static final boolean DEBUG_DEXOPT = false; 268 private static final boolean DEBUG_ABI_SELECTION = false; 269 270 static final boolean RUNTIME_PERMISSIONS_ENABLED = true; 271 272 private static final int RADIO_UID = Process.PHONE_UID; 273 private static final int LOG_UID = Process.LOG_UID; 274 private static final int NFC_UID = Process.NFC_UID; 275 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 276 private static final int SHELL_UID = Process.SHELL_UID; 277 278 // Cap the size of permission trees that 3rd party apps can define 279 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 280 281 // Suffix used during package installation when copying/moving 282 // package apks to install directory. 283 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 284 285 static final int SCAN_NO_DEX = 1<<1; 286 static final int SCAN_FORCE_DEX = 1<<2; 287 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 288 static final int SCAN_NEW_INSTALL = 1<<4; 289 static final int SCAN_NO_PATHS = 1<<5; 290 static final int SCAN_UPDATE_TIME = 1<<6; 291 static final int SCAN_DEFER_DEX = 1<<7; 292 static final int SCAN_BOOTING = 1<<8; 293 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 294 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 295 static final int SCAN_REPLACING = 1<<11; 296 static final int SCAN_REQUIRE_KNOWN = 1<<12; 297 298 static final int REMOVE_CHATTY = 1<<16; 299 300 /** 301 * Timeout (in milliseconds) after which the watchdog should declare that 302 * our handler thread is wedged. The usual default for such things is one 303 * minute but we sometimes do very lengthy I/O operations on this thread, 304 * such as installing multi-gigabyte applications, so ours needs to be longer. 305 */ 306 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 307 308 /** 309 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 310 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 311 * settings entry if available, otherwise we use the hardcoded default. If it's been 312 * more than this long since the last fstrim, we force one during the boot sequence. 313 * 314 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 315 * one gets run at the next available charging+idle time. This final mandatory 316 * no-fstrim check kicks in only of the other scheduling criteria is never met. 317 */ 318 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 319 320 /** 321 * Whether verification is enabled by default. 322 */ 323 private static final boolean DEFAULT_VERIFY_ENABLE = true; 324 325 /** 326 * The default maximum time to wait for the verification agent to return in 327 * milliseconds. 328 */ 329 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 330 331 /** 332 * The default response for package verification timeout. 333 * 334 * This can be either PackageManager.VERIFICATION_ALLOW or 335 * PackageManager.VERIFICATION_REJECT. 336 */ 337 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 338 339 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 340 341 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 342 DEFAULT_CONTAINER_PACKAGE, 343 "com.android.defcontainer.DefaultContainerService"); 344 345 private static final String KILL_APP_REASON_GIDS_CHANGED = 346 "permission grant or revoke changed gids"; 347 348 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 349 "permissions revoked"; 350 351 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 352 353 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 354 355 /** Permission grant: not grant the permission. */ 356 private static final int GRANT_DENIED = 1; 357 358 /** Permission grant: grant the permission as an install permission. */ 359 private static final int GRANT_INSTALL = 2; 360 361 /** Permission grant: grant the permission as a runtime one. */ 362 private static final int GRANT_RUNTIME = 3; 363 364 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 365 private static final int GRANT_UPGRADE = 4; 366 367 final ServiceThread mHandlerThread; 368 369 final PackageHandler mHandler; 370 371 /** 372 * Messages for {@link #mHandler} that need to wait for system ready before 373 * being dispatched. 374 */ 375 private ArrayList<Message> mPostSystemReadyMessages; 376 377 final int mSdkVersion = Build.VERSION.SDK_INT; 378 379 final Context mContext; 380 final boolean mFactoryTest; 381 final boolean mOnlyCore; 382 final boolean mLazyDexOpt; 383 final long mDexOptLRUThresholdInMills; 384 final DisplayMetrics mMetrics; 385 final int mDefParseFlags; 386 final String[] mSeparateProcesses; 387 final boolean mIsUpgrade; 388 389 // This is where all application persistent data goes. 390 final File mAppDataDir; 391 392 // This is where all application persistent data goes for secondary users. 393 final File mUserAppDataDir; 394 395 /** The location for ASEC container files on internal storage. */ 396 final String mAsecInternalPath; 397 398 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 399 // LOCK HELD. Can be called with mInstallLock held. 400 final Installer mInstaller; 401 402 /** Directory where installed third-party apps stored */ 403 final File mAppInstallDir; 404 405 /** 406 * Directory to which applications installed internally have their 407 * 32 bit native libraries copied. 408 */ 409 private File mAppLib32InstallDir; 410 411 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 412 // apps. 413 final File mDrmAppPrivateInstallDir; 414 415 // ---------------------------------------------------------------- 416 417 // Lock for state used when installing and doing other long running 418 // operations. Methods that must be called with this lock held have 419 // the suffix "LI". 420 final Object mInstallLock = new Object(); 421 422 // ---------------------------------------------------------------- 423 424 // Keys are String (package name), values are Package. This also serves 425 // as the lock for the global state. Methods that must be called with 426 // this lock held have the prefix "LP". 427 final ArrayMap<String, PackageParser.Package> mPackages = 428 new ArrayMap<String, PackageParser.Package>(); 429 430 // Tracks available target package names -> overlay package paths. 431 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 432 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 433 434 final Settings mSettings; 435 boolean mRestoredSettings; 436 437 // System configuration read by SystemConfig. 438 final int[] mGlobalGids; 439 final SparseArray<ArraySet<String>> mSystemPermissions; 440 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 441 442 // If mac_permissions.xml was found for seinfo labeling. 443 boolean mFoundPolicyFile; 444 445 // If a recursive restorecon of /data/data/<pkg> is needed. 446 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 447 448 public static final class SharedLibraryEntry { 449 public final String path; 450 public final String apk; 451 452 SharedLibraryEntry(String _path, String _apk) { 453 path = _path; 454 apk = _apk; 455 } 456 } 457 458 // Currently known shared libraries. 459 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 460 new ArrayMap<String, SharedLibraryEntry>(); 461 462 // All available activities, for your resolving pleasure. 463 final ActivityIntentResolver mActivities = 464 new ActivityIntentResolver(); 465 466 // All available receivers, for your resolving pleasure. 467 final ActivityIntentResolver mReceivers = 468 new ActivityIntentResolver(); 469 470 // All available services, for your resolving pleasure. 471 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 472 473 // All available providers, for your resolving pleasure. 474 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 475 476 // Mapping from provider base names (first directory in content URI codePath) 477 // to the provider information. 478 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 479 new ArrayMap<String, PackageParser.Provider>(); 480 481 // Mapping from instrumentation class names to info about them. 482 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 483 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 484 485 // Mapping from permission names to info about them. 486 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 487 new ArrayMap<String, PackageParser.PermissionGroup>(); 488 489 // Packages whose data we have transfered into another package, thus 490 // should no longer exist. 491 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 492 493 // Broadcast actions that are only available to the system. 494 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 495 496 /** List of packages waiting for verification. */ 497 final SparseArray<PackageVerificationState> mPendingVerification 498 = new SparseArray<PackageVerificationState>(); 499 500 /** Set of packages associated with each app op permission. */ 501 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 502 503 final PackageInstallerService mInstallerService; 504 505 private final PackageDexOptimizer mPackageDexOptimizer; 506 // Cache of users who need badging. 507 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 508 509 /** Token for keys in mPendingVerification. */ 510 private int mPendingVerificationToken = 0; 511 512 volatile boolean mSystemReady; 513 volatile boolean mSafeMode; 514 volatile boolean mHasSystemUidErrors; 515 516 ApplicationInfo mAndroidApplication; 517 final ActivityInfo mResolveActivity = new ActivityInfo(); 518 final ResolveInfo mResolveInfo = new ResolveInfo(); 519 ComponentName mResolveComponentName; 520 PackageParser.Package mPlatformPackage; 521 ComponentName mCustomResolverComponentName; 522 523 boolean mResolverReplaced = false; 524 525 private final ComponentName mIntentFilterVerifierComponent; 526 private int mIntentFilterVerificationToken = 0; 527 528 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 529 = new SparseArray<IntentFilterVerificationState>(); 530 531 private interface IntentFilterVerifier<T extends IntentFilter> { 532 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 533 T filter, String packageName); 534 void startVerifications(int userId); 535 void receiveVerificationResponse(int verificationId); 536 } 537 538 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 539 private Context mContext; 540 private ComponentName mIntentFilterVerifierComponent; 541 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 542 543 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 544 mContext = context; 545 mIntentFilterVerifierComponent = verifierComponent; 546 } 547 548 private String getDefaultScheme() { 549 // TODO: replace SCHEME_HTTP with SCHEME_HTTPS 550 return IntentFilter.SCHEME_HTTP; 551 } 552 553 @Override 554 public void startVerifications(int userId) { 555 // Launch verifications requests 556 int count = mCurrentIntentFilterVerifications.size(); 557 for (int n=0; n<count; n++) { 558 int verificationId = mCurrentIntentFilterVerifications.get(n); 559 final IntentFilterVerificationState ivs = 560 mIntentFilterVerificationStates.get(verificationId); 561 562 String packageName = ivs.getPackageName(); 563 564 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 565 final int filterCount = filters.size(); 566 ArraySet<String> domainsSet = new ArraySet<>(); 567 for (int m=0; m<filterCount; m++) { 568 PackageParser.ActivityIntentInfo filter = filters.get(m); 569 domainsSet.addAll(filter.getHostsList()); 570 } 571 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 572 synchronized (mPackages) { 573 if (mSettings.createIntentFilterVerificationIfNeededLPw( 574 packageName, domainsList) != null) { 575 scheduleWriteSettingsLocked(); 576 } 577 } 578 sendVerificationRequest(userId, verificationId, ivs); 579 } 580 mCurrentIntentFilterVerifications.clear(); 581 } 582 583 private void sendVerificationRequest(int userId, int verificationId, 584 IntentFilterVerificationState ivs) { 585 586 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 587 verificationIntent.putExtra( 588 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 589 verificationId); 590 verificationIntent.putExtra( 591 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 592 getDefaultScheme()); 593 verificationIntent.putExtra( 594 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 595 ivs.getHostsString()); 596 verificationIntent.putExtra( 597 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 598 ivs.getPackageName()); 599 verificationIntent.setComponent(mIntentFilterVerifierComponent); 600 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 601 602 UserHandle user = new UserHandle(userId); 603 mContext.sendBroadcastAsUser(verificationIntent, user); 604 Slog.d(TAG, "Sending IntenFilter verification broadcast"); 605 } 606 607 public void receiveVerificationResponse(int verificationId) { 608 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 609 610 final boolean verified = ivs.isVerified(); 611 612 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 613 final int count = filters.size(); 614 for (int n=0; n<count; n++) { 615 PackageParser.ActivityIntentInfo filter = filters.get(n); 616 filter.setVerified(verified); 617 618 Slog.d(TAG, "IntentFilter " + filter.toString() + " verified with result:" 619 + verified + " and hosts:" + ivs.getHostsString()); 620 } 621 622 mIntentFilterVerificationStates.remove(verificationId); 623 624 final String packageName = ivs.getPackageName(); 625 IntentFilterVerificationInfo ivi = null; 626 627 synchronized (mPackages) { 628 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 629 } 630 if (ivi == null) { 631 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 632 + verificationId + " packageName:" + packageName); 633 return; 634 } 635 Slog.d(TAG, "Updating IntentFilterVerificationInfo for verificationId: " 636 + verificationId); 637 638 synchronized (mPackages) { 639 if (verified) { 640 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 641 } else { 642 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 643 } 644 scheduleWriteSettingsLocked(); 645 646 final int userId = ivs.getUserId(); 647 if (userId != UserHandle.USER_ALL) { 648 final int userStatus = 649 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 650 651 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 652 boolean needUpdate = false; 653 654 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 655 // already been set by the User thru the Disambiguation dialog 656 switch (userStatus) { 657 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 658 if (verified) { 659 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 660 } else { 661 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 662 } 663 needUpdate = true; 664 break; 665 666 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 667 if (verified) { 668 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 669 needUpdate = true; 670 } 671 break; 672 673 default: 674 // Nothing to do 675 } 676 677 if (needUpdate) { 678 mSettings.updateIntentFilterVerificationStatusLPw( 679 packageName, updatedStatus, userId); 680 scheduleWritePackageRestrictionsLocked(userId); 681 } 682 } 683 } 684 } 685 686 @Override 687 public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 688 ActivityIntentInfo filter, String packageName) { 689 if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 690 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 691 Slog.d(TAG, "IntentFilter does not contain HTTP nor HTTPS data scheme"); 692 return false; 693 } 694 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 695 if (ivs == null) { 696 ivs = createDomainVerificationState(verifierId, userId, verificationId, 697 packageName); 698 } 699 if (!hasValidDomains(filter)) { 700 return false; 701 } 702 ivs.addFilter(filter); 703 return true; 704 } 705 706 private IntentFilterVerificationState createDomainVerificationState(int verifierId, 707 int userId, int verificationId, String packageName) { 708 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 709 verifierId, userId, packageName); 710 ivs.setPendingState(); 711 synchronized (mPackages) { 712 mIntentFilterVerificationStates.append(verificationId, ivs); 713 mCurrentIntentFilterVerifications.add(verificationId); 714 } 715 return ivs; 716 } 717 } 718 719 private static boolean hasValidDomains(ActivityIntentInfo filter) { 720 return hasValidDomains(filter, true); 721 } 722 723 private static boolean hasValidDomains(ActivityIntentInfo filter, boolean logging) { 724 boolean hasHTTPorHTTPS = filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 725 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS); 726 if (!hasHTTPorHTTPS) { 727 if (logging) { 728 Slog.d(TAG, "IntentFilter does not contain any HTTP or HTTPS data scheme"); 729 } 730 return false; 731 } 732 ArrayList<String> hosts = filter.getHostsList(); 733 if (hosts.size() == 0) { 734 if (logging) { 735 Slog.d(TAG, "IntentFilter does not contain any data hosts"); 736 } 737 // We still return true as this is the case of any Browser 738 return true; 739 } 740 String hostEndBase = null; 741 for (String host : hosts) { 742 String[] hostParts = host.split("\\."); 743 // Should be at minimum a host like "example.com" 744 if (hostParts.length < 2) { 745 if (logging) { 746 Slog.d(TAG, "IntentFilter does not contain a valid data host name: " + host); 747 } 748 return false; 749 } 750 // Verify that we have the same ending domain 751 int length = hostParts.length; 752 String hostEnd = hostParts[length - 1] + hostParts[length - 2]; 753 if (hostEndBase == null) { 754 hostEndBase = hostEnd; 755 } 756 if (!hostEnd.equalsIgnoreCase(hostEndBase)) { 757 if (logging) { 758 Slog.d(TAG, "IntentFilter does not contain the same data domains"); 759 } 760 return false; 761 } 762 } 763 return true; 764 } 765 766 private IntentFilterVerifier mIntentFilterVerifier; 767 768 // Set of pending broadcasts for aggregating enable/disable of components. 769 static class PendingPackageBroadcasts { 770 // for each user id, a map of <package name -> components within that package> 771 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 772 773 public PendingPackageBroadcasts() { 774 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 775 } 776 777 public ArrayList<String> get(int userId, String packageName) { 778 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 779 return packages.get(packageName); 780 } 781 782 public void put(int userId, String packageName, ArrayList<String> components) { 783 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 784 packages.put(packageName, components); 785 } 786 787 public void remove(int userId, String packageName) { 788 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 789 if (packages != null) { 790 packages.remove(packageName); 791 } 792 } 793 794 public void remove(int userId) { 795 mUidMap.remove(userId); 796 } 797 798 public int userIdCount() { 799 return mUidMap.size(); 800 } 801 802 public int userIdAt(int n) { 803 return mUidMap.keyAt(n); 804 } 805 806 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 807 return mUidMap.get(userId); 808 } 809 810 public int size() { 811 // total number of pending broadcast entries across all userIds 812 int num = 0; 813 for (int i = 0; i< mUidMap.size(); i++) { 814 num += mUidMap.valueAt(i).size(); 815 } 816 return num; 817 } 818 819 public void clear() { 820 mUidMap.clear(); 821 } 822 823 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 824 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 825 if (map == null) { 826 map = new ArrayMap<String, ArrayList<String>>(); 827 mUidMap.put(userId, map); 828 } 829 return map; 830 } 831 } 832 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 833 834 // Service Connection to remote media container service to copy 835 // package uri's from external media onto secure containers 836 // or internal storage. 837 private IMediaContainerService mContainerService = null; 838 839 static final int SEND_PENDING_BROADCAST = 1; 840 static final int MCS_BOUND = 3; 841 static final int END_COPY = 4; 842 static final int INIT_COPY = 5; 843 static final int MCS_UNBIND = 6; 844 static final int START_CLEANING_PACKAGE = 7; 845 static final int FIND_INSTALL_LOC = 8; 846 static final int POST_INSTALL = 9; 847 static final int MCS_RECONNECT = 10; 848 static final int MCS_GIVE_UP = 11; 849 static final int UPDATED_MEDIA_STATUS = 12; 850 static final int WRITE_SETTINGS = 13; 851 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 852 static final int PACKAGE_VERIFIED = 15; 853 static final int CHECK_PENDING_VERIFICATION = 16; 854 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 855 static final int INTENT_FILTER_VERIFIED = 18; 856 857 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 858 859 // Delay time in millisecs 860 static final int BROADCAST_DELAY = 10 * 1000; 861 862 static UserManagerService sUserManager; 863 864 // Stores a list of users whose package restrictions file needs to be updated 865 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 866 867 final private DefaultContainerConnection mDefContainerConn = 868 new DefaultContainerConnection(); 869 class DefaultContainerConnection implements ServiceConnection { 870 public void onServiceConnected(ComponentName name, IBinder service) { 871 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 872 IMediaContainerService imcs = 873 IMediaContainerService.Stub.asInterface(service); 874 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 875 } 876 877 public void onServiceDisconnected(ComponentName name) { 878 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 879 } 880 }; 881 882 // Recordkeeping of restore-after-install operations that are currently in flight 883 // between the Package Manager and the Backup Manager 884 class PostInstallData { 885 public InstallArgs args; 886 public PackageInstalledInfo res; 887 888 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 889 args = _a; 890 res = _r; 891 } 892 }; 893 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 894 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 895 896 // backup/restore of preferred activity state 897 private static final String TAG_PREFERRED_BACKUP = "pa"; 898 899 private final String mRequiredVerifierPackage; 900 901 private final PackageUsage mPackageUsage = new PackageUsage(); 902 903 private class PackageUsage { 904 private static final int WRITE_INTERVAL 905 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 906 907 private final Object mFileLock = new Object(); 908 private final AtomicLong mLastWritten = new AtomicLong(0); 909 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 910 911 private boolean mIsHistoricalPackageUsageAvailable = true; 912 913 boolean isHistoricalPackageUsageAvailable() { 914 return mIsHistoricalPackageUsageAvailable; 915 } 916 917 void write(boolean force) { 918 if (force) { 919 writeInternal(); 920 return; 921 } 922 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 923 && !DEBUG_DEXOPT) { 924 return; 925 } 926 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 927 new Thread("PackageUsage_DiskWriter") { 928 @Override 929 public void run() { 930 try { 931 writeInternal(); 932 } finally { 933 mBackgroundWriteRunning.set(false); 934 } 935 } 936 }.start(); 937 } 938 } 939 940 private void writeInternal() { 941 synchronized (mPackages) { 942 synchronized (mFileLock) { 943 AtomicFile file = getFile(); 944 FileOutputStream f = null; 945 try { 946 f = file.startWrite(); 947 BufferedOutputStream out = new BufferedOutputStream(f); 948 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 949 StringBuilder sb = new StringBuilder(); 950 for (PackageParser.Package pkg : mPackages.values()) { 951 if (pkg.mLastPackageUsageTimeInMills == 0) { 952 continue; 953 } 954 sb.setLength(0); 955 sb.append(pkg.packageName); 956 sb.append(' '); 957 sb.append((long)pkg.mLastPackageUsageTimeInMills); 958 sb.append('\n'); 959 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 960 } 961 out.flush(); 962 file.finishWrite(f); 963 } catch (IOException e) { 964 if (f != null) { 965 file.failWrite(f); 966 } 967 Log.e(TAG, "Failed to write package usage times", e); 968 } 969 } 970 } 971 mLastWritten.set(SystemClock.elapsedRealtime()); 972 } 973 974 void readLP() { 975 synchronized (mFileLock) { 976 AtomicFile file = getFile(); 977 BufferedInputStream in = null; 978 try { 979 in = new BufferedInputStream(file.openRead()); 980 StringBuffer sb = new StringBuffer(); 981 while (true) { 982 String packageName = readToken(in, sb, ' '); 983 if (packageName == null) { 984 break; 985 } 986 String timeInMillisString = readToken(in, sb, '\n'); 987 if (timeInMillisString == null) { 988 throw new IOException("Failed to find last usage time for package " 989 + packageName); 990 } 991 PackageParser.Package pkg = mPackages.get(packageName); 992 if (pkg == null) { 993 continue; 994 } 995 long timeInMillis; 996 try { 997 timeInMillis = Long.parseLong(timeInMillisString.toString()); 998 } catch (NumberFormatException e) { 999 throw new IOException("Failed to parse " + timeInMillisString 1000 + " as a long.", e); 1001 } 1002 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1003 } 1004 } catch (FileNotFoundException expected) { 1005 mIsHistoricalPackageUsageAvailable = false; 1006 } catch (IOException e) { 1007 Log.w(TAG, "Failed to read package usage times", e); 1008 } finally { 1009 IoUtils.closeQuietly(in); 1010 } 1011 } 1012 mLastWritten.set(SystemClock.elapsedRealtime()); 1013 } 1014 1015 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1016 throws IOException { 1017 sb.setLength(0); 1018 while (true) { 1019 int ch = in.read(); 1020 if (ch == -1) { 1021 if (sb.length() == 0) { 1022 return null; 1023 } 1024 throw new IOException("Unexpected EOF"); 1025 } 1026 if (ch == endOfToken) { 1027 return sb.toString(); 1028 } 1029 sb.append((char)ch); 1030 } 1031 } 1032 1033 private AtomicFile getFile() { 1034 File dataDir = Environment.getDataDirectory(); 1035 File systemDir = new File(dataDir, "system"); 1036 File fname = new File(systemDir, "package-usage.list"); 1037 return new AtomicFile(fname); 1038 } 1039 } 1040 1041 class PackageHandler extends Handler { 1042 private boolean mBound = false; 1043 final ArrayList<HandlerParams> mPendingInstalls = 1044 new ArrayList<HandlerParams>(); 1045 1046 private boolean connectToService() { 1047 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1048 " DefaultContainerService"); 1049 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1050 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1051 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1052 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 1053 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1054 mBound = true; 1055 return true; 1056 } 1057 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1058 return false; 1059 } 1060 1061 private void disconnectService() { 1062 mContainerService = null; 1063 mBound = false; 1064 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1065 mContext.unbindService(mDefContainerConn); 1066 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1067 } 1068 1069 PackageHandler(Looper looper) { 1070 super(looper); 1071 } 1072 1073 public void handleMessage(Message msg) { 1074 try { 1075 doHandleMessage(msg); 1076 } finally { 1077 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1078 } 1079 } 1080 1081 void doHandleMessage(Message msg) { 1082 switch (msg.what) { 1083 case INIT_COPY: { 1084 HandlerParams params = (HandlerParams) msg.obj; 1085 int idx = mPendingInstalls.size(); 1086 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1087 // If a bind was already initiated we dont really 1088 // need to do anything. The pending install 1089 // will be processed later on. 1090 if (!mBound) { 1091 // If this is the only one pending we might 1092 // have to bind to the service again. 1093 if (!connectToService()) { 1094 Slog.e(TAG, "Failed to bind to media container service"); 1095 params.serviceError(); 1096 return; 1097 } else { 1098 // Once we bind to the service, the first 1099 // pending request will be processed. 1100 mPendingInstalls.add(idx, params); 1101 } 1102 } else { 1103 mPendingInstalls.add(idx, params); 1104 // Already bound to the service. Just make 1105 // sure we trigger off processing the first request. 1106 if (idx == 0) { 1107 mHandler.sendEmptyMessage(MCS_BOUND); 1108 } 1109 } 1110 break; 1111 } 1112 case MCS_BOUND: { 1113 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1114 if (msg.obj != null) { 1115 mContainerService = (IMediaContainerService) msg.obj; 1116 } 1117 if (mContainerService == null) { 1118 // Something seriously wrong. Bail out 1119 Slog.e(TAG, "Cannot bind to media container service"); 1120 for (HandlerParams params : mPendingInstalls) { 1121 // Indicate service bind error 1122 params.serviceError(); 1123 } 1124 mPendingInstalls.clear(); 1125 } else if (mPendingInstalls.size() > 0) { 1126 HandlerParams params = mPendingInstalls.get(0); 1127 if (params != null) { 1128 if (params.startCopy()) { 1129 // We are done... look for more work or to 1130 // go idle. 1131 if (DEBUG_SD_INSTALL) Log.i(TAG, 1132 "Checking for more work or unbind..."); 1133 // Delete pending install 1134 if (mPendingInstalls.size() > 0) { 1135 mPendingInstalls.remove(0); 1136 } 1137 if (mPendingInstalls.size() == 0) { 1138 if (mBound) { 1139 if (DEBUG_SD_INSTALL) Log.i(TAG, 1140 "Posting delayed MCS_UNBIND"); 1141 removeMessages(MCS_UNBIND); 1142 Message ubmsg = obtainMessage(MCS_UNBIND); 1143 // Unbind after a little delay, to avoid 1144 // continual thrashing. 1145 sendMessageDelayed(ubmsg, 10000); 1146 } 1147 } else { 1148 // There are more pending requests in queue. 1149 // Just post MCS_BOUND message to trigger processing 1150 // of next pending install. 1151 if (DEBUG_SD_INSTALL) Log.i(TAG, 1152 "Posting MCS_BOUND for next work"); 1153 mHandler.sendEmptyMessage(MCS_BOUND); 1154 } 1155 } 1156 } 1157 } else { 1158 // Should never happen ideally. 1159 Slog.w(TAG, "Empty queue"); 1160 } 1161 break; 1162 } 1163 case MCS_RECONNECT: { 1164 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1165 if (mPendingInstalls.size() > 0) { 1166 if (mBound) { 1167 disconnectService(); 1168 } 1169 if (!connectToService()) { 1170 Slog.e(TAG, "Failed to bind to media container service"); 1171 for (HandlerParams params : mPendingInstalls) { 1172 // Indicate service bind error 1173 params.serviceError(); 1174 } 1175 mPendingInstalls.clear(); 1176 } 1177 } 1178 break; 1179 } 1180 case MCS_UNBIND: { 1181 // If there is no actual work left, then time to unbind. 1182 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1183 1184 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1185 if (mBound) { 1186 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1187 1188 disconnectService(); 1189 } 1190 } else if (mPendingInstalls.size() > 0) { 1191 // There are more pending requests in queue. 1192 // Just post MCS_BOUND message to trigger processing 1193 // of next pending install. 1194 mHandler.sendEmptyMessage(MCS_BOUND); 1195 } 1196 1197 break; 1198 } 1199 case MCS_GIVE_UP: { 1200 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1201 mPendingInstalls.remove(0); 1202 break; 1203 } 1204 case SEND_PENDING_BROADCAST: { 1205 String packages[]; 1206 ArrayList<String> components[]; 1207 int size = 0; 1208 int uids[]; 1209 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1210 synchronized (mPackages) { 1211 if (mPendingBroadcasts == null) { 1212 return; 1213 } 1214 size = mPendingBroadcasts.size(); 1215 if (size <= 0) { 1216 // Nothing to be done. Just return 1217 return; 1218 } 1219 packages = new String[size]; 1220 components = new ArrayList[size]; 1221 uids = new int[size]; 1222 int i = 0; // filling out the above arrays 1223 1224 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1225 int packageUserId = mPendingBroadcasts.userIdAt(n); 1226 Iterator<Map.Entry<String, ArrayList<String>>> it 1227 = mPendingBroadcasts.packagesForUserId(packageUserId) 1228 .entrySet().iterator(); 1229 while (it.hasNext() && i < size) { 1230 Map.Entry<String, ArrayList<String>> ent = it.next(); 1231 packages[i] = ent.getKey(); 1232 components[i] = ent.getValue(); 1233 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1234 uids[i] = (ps != null) 1235 ? UserHandle.getUid(packageUserId, ps.appId) 1236 : -1; 1237 i++; 1238 } 1239 } 1240 size = i; 1241 mPendingBroadcasts.clear(); 1242 } 1243 // Send broadcasts 1244 for (int i = 0; i < size; i++) { 1245 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1246 } 1247 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1248 break; 1249 } 1250 case START_CLEANING_PACKAGE: { 1251 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1252 final String packageName = (String)msg.obj; 1253 final int userId = msg.arg1; 1254 final boolean andCode = msg.arg2 != 0; 1255 synchronized (mPackages) { 1256 if (userId == UserHandle.USER_ALL) { 1257 int[] users = sUserManager.getUserIds(); 1258 for (int user : users) { 1259 mSettings.addPackageToCleanLPw( 1260 new PackageCleanItem(user, packageName, andCode)); 1261 } 1262 } else { 1263 mSettings.addPackageToCleanLPw( 1264 new PackageCleanItem(userId, packageName, andCode)); 1265 } 1266 } 1267 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1268 startCleaningPackages(); 1269 } break; 1270 case POST_INSTALL: { 1271 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1272 PostInstallData data = mRunningInstalls.get(msg.arg1); 1273 mRunningInstalls.delete(msg.arg1); 1274 boolean deleteOld = false; 1275 1276 if (data != null) { 1277 InstallArgs args = data.args; 1278 PackageInstalledInfo res = data.res; 1279 1280 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1281 res.removedInfo.sendBroadcast(false, true, false); 1282 Bundle extras = new Bundle(1); 1283 extras.putInt(Intent.EXTRA_UID, res.uid); 1284 1285 // Now that we successfully installed the package, grant runtime 1286 // permissions if requested before broadcasting the install. 1287 if ((args.installFlags 1288 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { 1289 grantRequestedRuntimePermissions(res.pkg, 1290 args.user.getIdentifier()); 1291 } 1292 1293 // Determine the set of users who are adding this 1294 // package for the first time vs. those who are seeing 1295 // an update. 1296 int[] firstUsers; 1297 int[] updateUsers = new int[0]; 1298 if (res.origUsers == null || res.origUsers.length == 0) { 1299 firstUsers = res.newUsers; 1300 } else { 1301 firstUsers = new int[0]; 1302 for (int i=0; i<res.newUsers.length; i++) { 1303 int user = res.newUsers[i]; 1304 boolean isNew = true; 1305 for (int j=0; j<res.origUsers.length; j++) { 1306 if (res.origUsers[j] == user) { 1307 isNew = false; 1308 break; 1309 } 1310 } 1311 if (isNew) { 1312 int[] newFirst = new int[firstUsers.length+1]; 1313 System.arraycopy(firstUsers, 0, newFirst, 0, 1314 firstUsers.length); 1315 newFirst[firstUsers.length] = user; 1316 firstUsers = newFirst; 1317 } else { 1318 int[] newUpdate = new int[updateUsers.length+1]; 1319 System.arraycopy(updateUsers, 0, newUpdate, 0, 1320 updateUsers.length); 1321 newUpdate[updateUsers.length] = user; 1322 updateUsers = newUpdate; 1323 } 1324 } 1325 } 1326 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1327 res.pkg.applicationInfo.packageName, 1328 extras, null, null, firstUsers); 1329 final boolean update = res.removedInfo.removedPackage != null; 1330 if (update) { 1331 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1332 } 1333 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1334 res.pkg.applicationInfo.packageName, 1335 extras, null, null, updateUsers); 1336 if (update) { 1337 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1338 res.pkg.applicationInfo.packageName, 1339 extras, null, null, updateUsers); 1340 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1341 null, null, 1342 res.pkg.applicationInfo.packageName, null, updateUsers); 1343 1344 // treat asec-hosted packages like removable media on upgrade 1345 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1346 if (DEBUG_INSTALL) { 1347 Slog.i(TAG, "upgrading pkg " + res.pkg 1348 + " is ASEC-hosted -> AVAILABLE"); 1349 } 1350 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1351 ArrayList<String> pkgList = new ArrayList<String>(1); 1352 pkgList.add(res.pkg.applicationInfo.packageName); 1353 sendResourcesChangedBroadcast(true, true, 1354 pkgList,uidArray, null); 1355 } 1356 } 1357 if (res.removedInfo.args != null) { 1358 // Remove the replaced package's older resources safely now 1359 deleteOld = true; 1360 } 1361 1362 // Log current value of "unknown sources" setting 1363 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1364 getUnknownSourcesSettings()); 1365 } 1366 // Force a gc to clear up things 1367 Runtime.getRuntime().gc(); 1368 // We delete after a gc for applications on sdcard. 1369 if (deleteOld) { 1370 synchronized (mInstallLock) { 1371 res.removedInfo.args.doPostDeleteLI(true); 1372 } 1373 } 1374 if (args.observer != null) { 1375 try { 1376 Bundle extras = extrasForInstallResult(res); 1377 args.observer.onPackageInstalled(res.name, res.returnCode, 1378 res.returnMsg, extras); 1379 } catch (RemoteException e) { 1380 Slog.i(TAG, "Observer no longer exists."); 1381 } 1382 } 1383 } else { 1384 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1385 } 1386 } break; 1387 case UPDATED_MEDIA_STATUS: { 1388 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1389 boolean reportStatus = msg.arg1 == 1; 1390 boolean doGc = msg.arg2 == 1; 1391 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1392 if (doGc) { 1393 // Force a gc to clear up stale containers. 1394 Runtime.getRuntime().gc(); 1395 } 1396 if (msg.obj != null) { 1397 @SuppressWarnings("unchecked") 1398 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1399 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1400 // Unload containers 1401 unloadAllContainers(args); 1402 } 1403 if (reportStatus) { 1404 try { 1405 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1406 PackageHelper.getMountService().finishMediaUpdate(); 1407 } catch (RemoteException e) { 1408 Log.e(TAG, "MountService not running?"); 1409 } 1410 } 1411 } break; 1412 case WRITE_SETTINGS: { 1413 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1414 synchronized (mPackages) { 1415 removeMessages(WRITE_SETTINGS); 1416 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1417 mSettings.writeLPr(); 1418 mDirtyUsers.clear(); 1419 } 1420 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1421 } break; 1422 case WRITE_PACKAGE_RESTRICTIONS: { 1423 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1424 synchronized (mPackages) { 1425 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1426 for (int userId : mDirtyUsers) { 1427 mSettings.writePackageRestrictionsLPr(userId); 1428 } 1429 mDirtyUsers.clear(); 1430 } 1431 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1432 } break; 1433 case CHECK_PENDING_VERIFICATION: { 1434 final int verificationId = msg.arg1; 1435 final PackageVerificationState state = mPendingVerification.get(verificationId); 1436 1437 if ((state != null) && !state.timeoutExtended()) { 1438 final InstallArgs args = state.getInstallArgs(); 1439 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1440 1441 Slog.i(TAG, "Verification timed out for " + originUri); 1442 mPendingVerification.remove(verificationId); 1443 1444 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1445 1446 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1447 Slog.i(TAG, "Continuing with installation of " + originUri); 1448 state.setVerifierResponse(Binder.getCallingUid(), 1449 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1450 broadcastPackageVerified(verificationId, originUri, 1451 PackageManager.VERIFICATION_ALLOW, 1452 state.getInstallArgs().getUser()); 1453 try { 1454 ret = args.copyApk(mContainerService, true); 1455 } catch (RemoteException e) { 1456 Slog.e(TAG, "Could not contact the ContainerService"); 1457 } 1458 } else { 1459 broadcastPackageVerified(verificationId, originUri, 1460 PackageManager.VERIFICATION_REJECT, 1461 state.getInstallArgs().getUser()); 1462 } 1463 1464 processPendingInstall(args, ret); 1465 mHandler.sendEmptyMessage(MCS_UNBIND); 1466 } 1467 break; 1468 } 1469 case PACKAGE_VERIFIED: { 1470 final int verificationId = msg.arg1; 1471 1472 final PackageVerificationState state = mPendingVerification.get(verificationId); 1473 if (state == null) { 1474 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1475 break; 1476 } 1477 1478 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1479 1480 state.setVerifierResponse(response.callerUid, response.code); 1481 1482 if (state.isVerificationComplete()) { 1483 mPendingVerification.remove(verificationId); 1484 1485 final InstallArgs args = state.getInstallArgs(); 1486 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1487 1488 int ret; 1489 if (state.isInstallAllowed()) { 1490 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1491 broadcastPackageVerified(verificationId, originUri, 1492 response.code, state.getInstallArgs().getUser()); 1493 try { 1494 ret = args.copyApk(mContainerService, true); 1495 } catch (RemoteException e) { 1496 Slog.e(TAG, "Could not contact the ContainerService"); 1497 } 1498 } else { 1499 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1500 } 1501 1502 processPendingInstall(args, ret); 1503 1504 mHandler.sendEmptyMessage(MCS_UNBIND); 1505 } 1506 1507 break; 1508 } 1509 case START_INTENT_FILTER_VERIFICATIONS: { 1510 int userId = msg.arg1; 1511 int verifierUid = msg.arg2; 1512 PackageParser.Package pkg = (PackageParser.Package)msg.obj; 1513 1514 verifyIntentFiltersIfNeeded(userId, verifierUid, pkg); 1515 break; 1516 } 1517 case INTENT_FILTER_VERIFIED: { 1518 final int verificationId = msg.arg1; 1519 1520 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1521 verificationId); 1522 if (state == null) { 1523 Slog.w(TAG, "Invalid IntentFilter verification token " 1524 + verificationId + " received"); 1525 break; 1526 } 1527 1528 final int userId = state.getUserId(); 1529 1530 Slog.d(TAG, "Processing IntentFilter verification with token:" 1531 + verificationId + " and userId:" + userId); 1532 1533 final IntentFilterVerificationResponse response = 1534 (IntentFilterVerificationResponse) msg.obj; 1535 1536 state.setVerifierResponse(response.callerUid, response.code); 1537 1538 Slog.d(TAG, "IntentFilter verification with token:" + verificationId 1539 + " and userId:" + userId 1540 + " is settings verifier response with response code:" 1541 + response.code); 1542 1543 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1544 Slog.d(TAG, "Domains failing verification: " 1545 + response.getFailedDomainsString()); 1546 } 1547 1548 if (state.isVerificationComplete()) { 1549 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1550 } else { 1551 Slog.d(TAG, "IntentFilter verification with token:" + verificationId 1552 + " was not said to be complete"); 1553 } 1554 1555 break; 1556 } 1557 } 1558 } 1559 } 1560 1561 private StorageEventListener mStorageListener = new StorageEventListener() { 1562 @Override 1563 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1564 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1565 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1566 loadPrivatePackages(vol); 1567 } else if (vol.state == VolumeInfo.STATE_UNMOUNTING) { 1568 unloadPrivatePackages(vol); 1569 } 1570 } 1571 1572 if (vol.isPrimary() && vol.type == VolumeInfo.TYPE_PUBLIC) { 1573 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1574 updateExternalMediaStatus(true, false); 1575 } else if (vol.state == VolumeInfo.STATE_UNMOUNTING) { 1576 updateExternalMediaStatus(false, false); 1577 } 1578 } 1579 } 1580 }; 1581 1582 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) { 1583 if (userId >= UserHandle.USER_OWNER) { 1584 grantRequestedRuntimePermissionsForUser(pkg, userId); 1585 } else if (userId == UserHandle.USER_ALL) { 1586 for (int someUserId : UserManagerService.getInstance().getUserIds()) { 1587 grantRequestedRuntimePermissionsForUser(pkg, someUserId); 1588 } 1589 } 1590 } 1591 1592 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) { 1593 SettingBase sb = (SettingBase) pkg.mExtras; 1594 if (sb == null) { 1595 return; 1596 } 1597 1598 PermissionsState permissionsState = sb.getPermissionsState(); 1599 1600 for (String permission : pkg.requestedPermissions) { 1601 BasePermission bp = mSettings.mPermissions.get(permission); 1602 if (bp != null && bp.isRuntime()) { 1603 permissionsState.grantRuntimePermission(bp, userId); 1604 } 1605 } 1606 } 1607 1608 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1609 Bundle extras = null; 1610 switch (res.returnCode) { 1611 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1612 extras = new Bundle(); 1613 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1614 res.origPermission); 1615 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1616 res.origPackage); 1617 break; 1618 } 1619 } 1620 return extras; 1621 } 1622 1623 void scheduleWriteSettingsLocked() { 1624 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1625 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1626 } 1627 } 1628 1629 void scheduleWritePackageRestrictionsLocked(int userId) { 1630 if (!sUserManager.exists(userId)) return; 1631 mDirtyUsers.add(userId); 1632 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1633 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1634 } 1635 } 1636 1637 public static PackageManagerService main(Context context, Installer installer, 1638 boolean factoryTest, boolean onlyCore) { 1639 PackageManagerService m = new PackageManagerService(context, installer, 1640 factoryTest, onlyCore); 1641 ServiceManager.addService("package", m); 1642 return m; 1643 } 1644 1645 static String[] splitString(String str, char sep) { 1646 int count = 1; 1647 int i = 0; 1648 while ((i=str.indexOf(sep, i)) >= 0) { 1649 count++; 1650 i++; 1651 } 1652 1653 String[] res = new String[count]; 1654 i=0; 1655 count = 0; 1656 int lastI=0; 1657 while ((i=str.indexOf(sep, i)) >= 0) { 1658 res[count] = str.substring(lastI, i); 1659 count++; 1660 i++; 1661 lastI = i; 1662 } 1663 res[count] = str.substring(lastI, str.length()); 1664 return res; 1665 } 1666 1667 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1668 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1669 Context.DISPLAY_SERVICE); 1670 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1671 } 1672 1673 public PackageManagerService(Context context, Installer installer, 1674 boolean factoryTest, boolean onlyCore) { 1675 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1676 SystemClock.uptimeMillis()); 1677 1678 if (mSdkVersion <= 0) { 1679 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1680 } 1681 1682 mContext = context; 1683 mFactoryTest = factoryTest; 1684 mOnlyCore = onlyCore; 1685 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1686 mMetrics = new DisplayMetrics(); 1687 mSettings = new Settings(mPackages); 1688 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1689 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1690 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1691 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1692 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1693 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1694 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1695 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1696 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1697 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1698 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1699 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1700 1701 // TODO: add a property to control this? 1702 long dexOptLRUThresholdInMinutes; 1703 if (mLazyDexOpt) { 1704 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1705 } else { 1706 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1707 } 1708 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1709 1710 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1711 if (separateProcesses != null && separateProcesses.length() > 0) { 1712 if ("*".equals(separateProcesses)) { 1713 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1714 mSeparateProcesses = null; 1715 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1716 } else { 1717 mDefParseFlags = 0; 1718 mSeparateProcesses = separateProcesses.split(","); 1719 Slog.w(TAG, "Running with debug.separate_processes: " 1720 + separateProcesses); 1721 } 1722 } else { 1723 mDefParseFlags = 0; 1724 mSeparateProcesses = null; 1725 } 1726 1727 mInstaller = installer; 1728 mPackageDexOptimizer = new PackageDexOptimizer(this); 1729 1730 getDefaultDisplayMetrics(context, mMetrics); 1731 1732 SystemConfig systemConfig = SystemConfig.getInstance(); 1733 mGlobalGids = systemConfig.getGlobalGids(); 1734 mSystemPermissions = systemConfig.getSystemPermissions(); 1735 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1736 1737 synchronized (mInstallLock) { 1738 // writer 1739 synchronized (mPackages) { 1740 mHandlerThread = new ServiceThread(TAG, 1741 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1742 mHandlerThread.start(); 1743 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1744 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1745 1746 File dataDir = Environment.getDataDirectory(); 1747 mAppDataDir = new File(dataDir, "data"); 1748 mAppInstallDir = new File(dataDir, "app"); 1749 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1750 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1751 mUserAppDataDir = new File(dataDir, "user"); 1752 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1753 1754 sUserManager = new UserManagerService(context, this, 1755 mInstallLock, mPackages); 1756 1757 // Propagate permission configuration in to package manager. 1758 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1759 = systemConfig.getPermissions(); 1760 for (int i=0; i<permConfig.size(); i++) { 1761 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1762 BasePermission bp = mSettings.mPermissions.get(perm.name); 1763 if (bp == null) { 1764 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1765 mSettings.mPermissions.put(perm.name, bp); 1766 } 1767 if (perm.gids != null) { 1768 bp.setGids(perm.gids, perm.perUser); 1769 } 1770 } 1771 1772 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1773 for (int i=0; i<libConfig.size(); i++) { 1774 mSharedLibraries.put(libConfig.keyAt(i), 1775 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1776 } 1777 1778 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1779 1780 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1781 mSdkVersion, mOnlyCore); 1782 1783 String customResolverActivity = Resources.getSystem().getString( 1784 R.string.config_customResolverActivity); 1785 if (TextUtils.isEmpty(customResolverActivity)) { 1786 customResolverActivity = null; 1787 } else { 1788 mCustomResolverComponentName = ComponentName.unflattenFromString( 1789 customResolverActivity); 1790 } 1791 1792 long startTime = SystemClock.uptimeMillis(); 1793 1794 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1795 startTime); 1796 1797 // Set flag to monitor and not change apk file paths when 1798 // scanning install directories. 1799 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1800 1801 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1802 1803 /** 1804 * Add everything in the in the boot class path to the 1805 * list of process files because dexopt will have been run 1806 * if necessary during zygote startup. 1807 */ 1808 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1809 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1810 1811 if (bootClassPath != null) { 1812 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1813 for (String element : bootClassPathElements) { 1814 alreadyDexOpted.add(element); 1815 } 1816 } else { 1817 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1818 } 1819 1820 if (systemServerClassPath != null) { 1821 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1822 for (String element : systemServerClassPathElements) { 1823 alreadyDexOpted.add(element); 1824 } 1825 } else { 1826 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 1827 } 1828 1829 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 1830 final String[] dexCodeInstructionSets = 1831 getDexCodeInstructionSets( 1832 allInstructionSets.toArray(new String[allInstructionSets.size()])); 1833 1834 /** 1835 * Ensure all external libraries have had dexopt run on them. 1836 */ 1837 if (mSharedLibraries.size() > 0) { 1838 // NOTE: For now, we're compiling these system "shared libraries" 1839 // (and framework jars) into all available architectures. It's possible 1840 // to compile them only when we come across an app that uses them (there's 1841 // already logic for that in scanPackageLI) but that adds some complexity. 1842 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1843 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1844 final String lib = libEntry.path; 1845 if (lib == null) { 1846 continue; 1847 } 1848 1849 try { 1850 byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null, 1851 dexCodeInstructionSet, 1852 false); 1853 if (dexoptRequired != DexFile.UP_TO_DATE) { 1854 alreadyDexOpted.add(lib); 1855 1856 // The list of "shared libraries" we have at this point is 1857 if (dexoptRequired == DexFile.DEXOPT_NEEDED) { 1858 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1859 } else { 1860 mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1861 } 1862 } 1863 } catch (FileNotFoundException e) { 1864 Slog.w(TAG, "Library not found: " + lib); 1865 } catch (IOException e) { 1866 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1867 + e.getMessage()); 1868 } 1869 } 1870 } 1871 } 1872 1873 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1874 1875 // Gross hack for now: we know this file doesn't contain any 1876 // code, so don't dexopt it to avoid the resulting log spew. 1877 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1878 1879 // Gross hack for now: we know this file is only part of 1880 // the boot class path for art, so don't dexopt it to 1881 // avoid the resulting log spew. 1882 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1883 1884 /** 1885 * And there are a number of commands implemented in Java, which 1886 * we currently need to do the dexopt on so that they can be 1887 * run from a non-root shell. 1888 */ 1889 String[] frameworkFiles = frameworkDir.list(); 1890 if (frameworkFiles != null) { 1891 // TODO: We could compile these only for the most preferred ABI. We should 1892 // first double check that the dex files for these commands are not referenced 1893 // by other system apps. 1894 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1895 for (int i=0; i<frameworkFiles.length; i++) { 1896 File libPath = new File(frameworkDir, frameworkFiles[i]); 1897 String path = libPath.getPath(); 1898 // Skip the file if we already did it. 1899 if (alreadyDexOpted.contains(path)) { 1900 continue; 1901 } 1902 // Skip the file if it is not a type we want to dexopt. 1903 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1904 continue; 1905 } 1906 try { 1907 byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null, 1908 dexCodeInstructionSet, 1909 false); 1910 if (dexoptRequired == DexFile.DEXOPT_NEEDED) { 1911 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1912 } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) { 1913 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1914 } 1915 } catch (FileNotFoundException e) { 1916 Slog.w(TAG, "Jar not found: " + path); 1917 } catch (IOException e) { 1918 Slog.w(TAG, "Exception reading jar: " + path, e); 1919 } 1920 } 1921 } 1922 } 1923 1924 // Collect vendor overlay packages. 1925 // (Do this before scanning any apps.) 1926 // For security and version matching reason, only consider 1927 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1928 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1929 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1930 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 1931 1932 // Find base frameworks (resource packages without code). 1933 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1934 | PackageParser.PARSE_IS_SYSTEM_DIR 1935 | PackageParser.PARSE_IS_PRIVILEGED, 1936 scanFlags | SCAN_NO_DEX, 0); 1937 1938 // Collected privileged system packages. 1939 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1940 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1941 | PackageParser.PARSE_IS_SYSTEM_DIR 1942 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 1943 1944 // Collect ordinary system packages. 1945 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1946 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1947 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1948 1949 // Collect all vendor packages. 1950 File vendorAppDir = new File("/vendor/app"); 1951 try { 1952 vendorAppDir = vendorAppDir.getCanonicalFile(); 1953 } catch (IOException e) { 1954 // failed to look up canonical path, continue with original one 1955 } 1956 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1957 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1958 1959 // Collect all OEM packages. 1960 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 1961 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 1962 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1963 1964 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1965 mInstaller.moveFiles(); 1966 1967 // Prune any system packages that no longer exist. 1968 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1969 final ArrayMap<String, File> expectingBetter = new ArrayMap<>(); 1970 if (!mOnlyCore) { 1971 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1972 while (psit.hasNext()) { 1973 PackageSetting ps = psit.next(); 1974 1975 /* 1976 * If this is not a system app, it can't be a 1977 * disable system app. 1978 */ 1979 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1980 continue; 1981 } 1982 1983 /* 1984 * If the package is scanned, it's not erased. 1985 */ 1986 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1987 if (scannedPkg != null) { 1988 /* 1989 * If the system app is both scanned and in the 1990 * disabled packages list, then it must have been 1991 * added via OTA. Remove it from the currently 1992 * scanned package so the previously user-installed 1993 * application can be scanned. 1994 */ 1995 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1996 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 1997 + ps.name + "; removing system app. Last known codePath=" 1998 + ps.codePathString + ", installStatus=" + ps.installStatus 1999 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2000 + scannedPkg.mVersionCode); 2001 removePackageLI(ps, true); 2002 expectingBetter.put(ps.name, ps.codePath); 2003 } 2004 2005 continue; 2006 } 2007 2008 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2009 psit.remove(); 2010 logCriticalInfo(Log.WARN, "System package " + ps.name 2011 + " no longer exists; wiping its data"); 2012 removeDataDirsLI(ps.name); 2013 } else { 2014 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2015 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2016 possiblyDeletedUpdatedSystemApps.add(ps.name); 2017 } 2018 } 2019 } 2020 } 2021 2022 //look for any incomplete package installations 2023 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2024 //clean up list 2025 for(int i = 0; i < deletePkgsList.size(); i++) { 2026 //clean up here 2027 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2028 } 2029 //delete tmp files 2030 deleteTempPackageFiles(); 2031 2032 // Remove any shared userIDs that have no associated packages 2033 mSettings.pruneSharedUsersLPw(); 2034 2035 if (!mOnlyCore) { 2036 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2037 SystemClock.uptimeMillis()); 2038 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2039 2040 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2041 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2042 2043 /** 2044 * Remove disable package settings for any updated system 2045 * apps that were removed via an OTA. If they're not a 2046 * previously-updated app, remove them completely. 2047 * Otherwise, just revoke their system-level permissions. 2048 */ 2049 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2050 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2051 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2052 2053 String msg; 2054 if (deletedPkg == null) { 2055 msg = "Updated system package " + deletedAppName 2056 + " no longer exists; wiping its data"; 2057 removeDataDirsLI(deletedAppName); 2058 } else { 2059 msg = "Updated system app + " + deletedAppName 2060 + " no longer present; removing system privileges for " 2061 + deletedAppName; 2062 2063 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2064 2065 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2066 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2067 } 2068 logCriticalInfo(Log.WARN, msg); 2069 } 2070 2071 /** 2072 * Make sure all system apps that we expected to appear on 2073 * the userdata partition actually showed up. If they never 2074 * appeared, crawl back and revive the system version. 2075 */ 2076 for (int i = 0; i < expectingBetter.size(); i++) { 2077 final String packageName = expectingBetter.keyAt(i); 2078 if (!mPackages.containsKey(packageName)) { 2079 final File scanFile = expectingBetter.valueAt(i); 2080 2081 logCriticalInfo(Log.WARN, "Expected better " + packageName 2082 + " but never showed up; reverting to system"); 2083 2084 final int reparseFlags; 2085 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2086 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2087 | PackageParser.PARSE_IS_SYSTEM_DIR 2088 | PackageParser.PARSE_IS_PRIVILEGED; 2089 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2090 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2091 | PackageParser.PARSE_IS_SYSTEM_DIR; 2092 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2093 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2094 | PackageParser.PARSE_IS_SYSTEM_DIR; 2095 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2096 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2097 | PackageParser.PARSE_IS_SYSTEM_DIR; 2098 } else { 2099 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2100 continue; 2101 } 2102 2103 mSettings.enableSystemPackageLPw(packageName); 2104 2105 try { 2106 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null); 2107 } catch (PackageManagerException e) { 2108 Slog.e(TAG, "Failed to parse original system package: " 2109 + e.getMessage()); 2110 } 2111 } 2112 } 2113 } 2114 2115 // Now that we know all of the shared libraries, update all clients to have 2116 // the correct library paths. 2117 updateAllSharedLibrariesLPw(); 2118 2119 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2120 // NOTE: We ignore potential failures here during a system scan (like 2121 // the rest of the commands above) because there's precious little we 2122 // can do about it. A settings error is reported, though. 2123 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2124 false /* force dexopt */, false /* defer dexopt */); 2125 } 2126 2127 // Now that we know all the packages we are keeping, 2128 // read and update their last usage times. 2129 mPackageUsage.readLP(); 2130 2131 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2132 SystemClock.uptimeMillis()); 2133 Slog.i(TAG, "Time to scan packages: " 2134 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2135 + " seconds"); 2136 2137 // If the platform SDK has changed since the last time we booted, 2138 // we need to re-grant app permission to catch any new ones that 2139 // appear. This is really a hack, and means that apps can in some 2140 // cases get permissions that the user didn't initially explicitly 2141 // allow... it would be nice to have some better way to handle 2142 // this situation. 2143 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 2144 != mSdkVersion; 2145 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 2146 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 2147 + "; regranting permissions for internal storage"); 2148 mSettings.mInternalSdkPlatform = mSdkVersion; 2149 2150 // For now runtime permissions are toggled via a system property. 2151 if (!RUNTIME_PERMISSIONS_ENABLED) { 2152 // Remove the runtime permissions state if the feature 2153 // was disabled by flipping the system property. 2154 mSettings.deleteRuntimePermissionsFiles(); 2155 } 2156 2157 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 2158 | (regrantPermissions 2159 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 2160 : 0)); 2161 2162 // If this is the first boot, and it is a normal boot, then 2163 // we need to initialize the default preferred apps. 2164 if (!mRestoredSettings && !onlyCore) { 2165 mSettings.readDefaultPreferredAppsLPw(this, 0); 2166 } 2167 2168 // If this is first boot after an OTA, and a normal boot, then 2169 // we need to clear code cache directories. 2170 mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint); 2171 if (mIsUpgrade && !onlyCore) { 2172 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2173 for (String pkgName : mSettings.mPackages.keySet()) { 2174 deleteCodeCacheDirsLI(pkgName); 2175 } 2176 mSettings.mFingerprint = Build.FINGERPRINT; 2177 } 2178 2179 // All the changes are done during package scanning. 2180 mSettings.updateInternalDatabaseVersion(); 2181 2182 // can downgrade to reader 2183 mSettings.writeLPr(); 2184 2185 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2186 SystemClock.uptimeMillis()); 2187 2188 mRequiredVerifierPackage = getRequiredVerifierLPr(); 2189 2190 mInstallerService = new PackageInstallerService(context, this); 2191 2192 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2193 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2194 mIntentFilterVerifierComponent); 2195 2196 primeDomainVerificationsLPw(false); 2197 2198 } // synchronized (mPackages) 2199 } // synchronized (mInstallLock) 2200 2201 // Now after opening every single application zip, make sure they 2202 // are all flushed. Not really needed, but keeps things nice and 2203 // tidy. 2204 Runtime.getRuntime().gc(); 2205 } 2206 2207 @Override 2208 public boolean isFirstBoot() { 2209 return !mRestoredSettings; 2210 } 2211 2212 @Override 2213 public boolean isOnlyCoreApps() { 2214 return mOnlyCore; 2215 } 2216 2217 @Override 2218 public boolean isUpgrade() { 2219 return mIsUpgrade; 2220 } 2221 2222 private String getRequiredVerifierLPr() { 2223 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2224 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2225 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 2226 2227 String requiredVerifier = null; 2228 2229 final int N = receivers.size(); 2230 for (int i = 0; i < N; i++) { 2231 final ResolveInfo info = receivers.get(i); 2232 2233 if (info.activityInfo == null) { 2234 continue; 2235 } 2236 2237 final String packageName = info.activityInfo.packageName; 2238 2239 if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 2240 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2241 continue; 2242 } 2243 2244 if (requiredVerifier != null) { 2245 throw new RuntimeException("There can be only one required verifier"); 2246 } 2247 2248 requiredVerifier = packageName; 2249 } 2250 2251 return requiredVerifier; 2252 } 2253 2254 private ComponentName getIntentFilterVerifierComponentNameLPr() { 2255 final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2256 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2257 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */); 2258 2259 ComponentName verifierComponentName = null; 2260 2261 int priority = -1000; 2262 final int N = receivers.size(); 2263 for (int i = 0; i < N; i++) { 2264 final ResolveInfo info = receivers.get(i); 2265 2266 if (info.activityInfo == null) { 2267 continue; 2268 } 2269 2270 final String packageName = info.activityInfo.packageName; 2271 2272 final PackageSetting ps = mSettings.mPackages.get(packageName); 2273 if (ps == null) { 2274 continue; 2275 } 2276 2277 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2278 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2279 continue; 2280 } 2281 2282 // Select the IntentFilterVerifier with the highest priority 2283 if (priority < info.priority) { 2284 priority = info.priority; 2285 verifierComponentName = new ComponentName(packageName, info.activityInfo.name); 2286 Slog.d(TAG, "Selecting IntentFilterVerifier: " + verifierComponentName + 2287 " with priority: " + info.priority); 2288 } 2289 } 2290 2291 return verifierComponentName; 2292 } 2293 2294 private void primeDomainVerificationsLPw(boolean logging) { 2295 Slog.d(TAG, "Start priming domain verification"); 2296 boolean updated = false; 2297 ArrayList<String> allHosts = new ArrayList<>(); 2298 for (PackageParser.Package pkg : mPackages.values()) { 2299 final String packageName = pkg.packageName; 2300 if (!hasDomainURLs(pkg)) { 2301 if (logging) { 2302 Slog.d(TAG, "No priming domain verifications for " + 2303 "package with no domain URLs: " + packageName); 2304 } 2305 continue; 2306 } 2307 for (PackageParser.Activity a : pkg.activities) { 2308 for (ActivityIntentInfo filter : a.intents) { 2309 if (hasValidDomains(filter, false)) { 2310 allHosts.addAll(filter.getHostsList()); 2311 } 2312 } 2313 } 2314 if (allHosts.size() > 0) { 2315 allHosts.add("*"); 2316 } 2317 IntentFilterVerificationInfo ivi = 2318 mSettings.createIntentFilterVerificationIfNeededLPw(packageName, allHosts); 2319 if (ivi != null) { 2320 // We will always log this 2321 Slog.d(TAG, "Priming domain verifications for package: " + packageName); 2322 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 2323 updated = true; 2324 } 2325 else { 2326 if (logging) { 2327 Slog.d(TAG, "No priming domain verifications for package: " + packageName); 2328 } 2329 } 2330 allHosts.clear(); 2331 } 2332 if (updated) { 2333 scheduleWriteSettingsLocked(); 2334 } 2335 Slog.d(TAG, "End priming domain verification"); 2336 } 2337 2338 @Override 2339 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2340 throws RemoteException { 2341 try { 2342 return super.onTransact(code, data, reply, flags); 2343 } catch (RuntimeException e) { 2344 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2345 Slog.wtf(TAG, "Package Manager Crash", e); 2346 } 2347 throw e; 2348 } 2349 } 2350 2351 void cleanupInstallFailedPackage(PackageSetting ps) { 2352 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2353 2354 removeDataDirsLI(ps.name); 2355 if (ps.codePath != null) { 2356 if (ps.codePath.isDirectory()) { 2357 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath()); 2358 } else { 2359 ps.codePath.delete(); 2360 } 2361 } 2362 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2363 if (ps.resourcePath.isDirectory()) { 2364 FileUtils.deleteContents(ps.resourcePath); 2365 } 2366 ps.resourcePath.delete(); 2367 } 2368 mSettings.removePackageLPw(ps.name); 2369 } 2370 2371 static int[] appendInts(int[] cur, int[] add) { 2372 if (add == null) return cur; 2373 if (cur == null) return add; 2374 final int N = add.length; 2375 for (int i=0; i<N; i++) { 2376 cur = appendInt(cur, add[i]); 2377 } 2378 return cur; 2379 } 2380 2381 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2382 if (!sUserManager.exists(userId)) return null; 2383 final PackageSetting ps = (PackageSetting) p.mExtras; 2384 if (ps == null) { 2385 return null; 2386 } 2387 2388 final PermissionsState permissionsState = ps.getPermissionsState(); 2389 2390 final int[] gids = permissionsState.computeGids(userId); 2391 final Set<String> permissions = permissionsState.getPermissions(userId); 2392 final PackageUserState state = ps.readUserState(userId); 2393 2394 return PackageParser.generatePackageInfo(p, gids, flags, 2395 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2396 } 2397 2398 @Override 2399 public boolean isPackageAvailable(String packageName, int userId) { 2400 if (!sUserManager.exists(userId)) return false; 2401 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 2402 synchronized (mPackages) { 2403 PackageParser.Package p = mPackages.get(packageName); 2404 if (p != null) { 2405 final PackageSetting ps = (PackageSetting) p.mExtras; 2406 if (ps != null) { 2407 final PackageUserState state = ps.readUserState(userId); 2408 if (state != null) { 2409 return PackageParser.isAvailable(state); 2410 } 2411 } 2412 } 2413 } 2414 return false; 2415 } 2416 2417 @Override 2418 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2419 if (!sUserManager.exists(userId)) return null; 2420 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 2421 // reader 2422 synchronized (mPackages) { 2423 PackageParser.Package p = mPackages.get(packageName); 2424 if (DEBUG_PACKAGE_INFO) 2425 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2426 if (p != null) { 2427 return generatePackageInfo(p, flags, userId); 2428 } 2429 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2430 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2431 } 2432 } 2433 return null; 2434 } 2435 2436 @Override 2437 public String[] currentToCanonicalPackageNames(String[] names) { 2438 String[] out = new String[names.length]; 2439 // reader 2440 synchronized (mPackages) { 2441 for (int i=names.length-1; i>=0; i--) { 2442 PackageSetting ps = mSettings.mPackages.get(names[i]); 2443 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2444 } 2445 } 2446 return out; 2447 } 2448 2449 @Override 2450 public String[] canonicalToCurrentPackageNames(String[] names) { 2451 String[] out = new String[names.length]; 2452 // reader 2453 synchronized (mPackages) { 2454 for (int i=names.length-1; i>=0; i--) { 2455 String cur = mSettings.mRenamedPackages.get(names[i]); 2456 out[i] = cur != null ? cur : names[i]; 2457 } 2458 } 2459 return out; 2460 } 2461 2462 @Override 2463 public int getPackageUid(String packageName, int userId) { 2464 if (!sUserManager.exists(userId)) return -1; 2465 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 2466 2467 // reader 2468 synchronized (mPackages) { 2469 PackageParser.Package p = mPackages.get(packageName); 2470 if(p != null) { 2471 return UserHandle.getUid(userId, p.applicationInfo.uid); 2472 } 2473 PackageSetting ps = mSettings.mPackages.get(packageName); 2474 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 2475 return -1; 2476 } 2477 p = ps.pkg; 2478 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 2479 } 2480 } 2481 2482 @Override 2483 public int[] getPackageGids(String packageName, int userId) throws RemoteException { 2484 if (!sUserManager.exists(userId)) { 2485 return null; 2486 } 2487 2488 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 2489 "getPackageGids"); 2490 2491 // reader 2492 synchronized (mPackages) { 2493 PackageParser.Package p = mPackages.get(packageName); 2494 if (DEBUG_PACKAGE_INFO) { 2495 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 2496 } 2497 if (p != null) { 2498 PackageSetting ps = (PackageSetting) p.mExtras; 2499 return ps.getPermissionsState().computeGids(userId); 2500 } 2501 } 2502 2503 return null; 2504 } 2505 2506 static PermissionInfo generatePermissionInfo( 2507 BasePermission bp, int flags) { 2508 if (bp.perm != null) { 2509 return PackageParser.generatePermissionInfo(bp.perm, flags); 2510 } 2511 PermissionInfo pi = new PermissionInfo(); 2512 pi.name = bp.name; 2513 pi.packageName = bp.sourcePackage; 2514 pi.nonLocalizedLabel = bp.name; 2515 pi.protectionLevel = bp.protectionLevel; 2516 return pi; 2517 } 2518 2519 @Override 2520 public PermissionInfo getPermissionInfo(String name, int flags) { 2521 // reader 2522 synchronized (mPackages) { 2523 final BasePermission p = mSettings.mPermissions.get(name); 2524 if (p != null) { 2525 return generatePermissionInfo(p, flags); 2526 } 2527 return null; 2528 } 2529 } 2530 2531 @Override 2532 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2533 // reader 2534 synchronized (mPackages) { 2535 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2536 for (BasePermission p : mSettings.mPermissions.values()) { 2537 if (group == null) { 2538 if (p.perm == null || p.perm.info.group == null) { 2539 out.add(generatePermissionInfo(p, flags)); 2540 } 2541 } else { 2542 if (p.perm != null && group.equals(p.perm.info.group)) { 2543 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2544 } 2545 } 2546 } 2547 2548 if (out.size() > 0) { 2549 return out; 2550 } 2551 return mPermissionGroups.containsKey(group) ? out : null; 2552 } 2553 } 2554 2555 @Override 2556 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2557 // reader 2558 synchronized (mPackages) { 2559 return PackageParser.generatePermissionGroupInfo( 2560 mPermissionGroups.get(name), flags); 2561 } 2562 } 2563 2564 @Override 2565 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2566 // reader 2567 synchronized (mPackages) { 2568 final int N = mPermissionGroups.size(); 2569 ArrayList<PermissionGroupInfo> out 2570 = new ArrayList<PermissionGroupInfo>(N); 2571 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2572 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2573 } 2574 return out; 2575 } 2576 } 2577 2578 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2579 int userId) { 2580 if (!sUserManager.exists(userId)) return null; 2581 PackageSetting ps = mSettings.mPackages.get(packageName); 2582 if (ps != null) { 2583 if (ps.pkg == null) { 2584 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2585 flags, userId); 2586 if (pInfo != null) { 2587 return pInfo.applicationInfo; 2588 } 2589 return null; 2590 } 2591 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2592 ps.readUserState(userId), userId); 2593 } 2594 return null; 2595 } 2596 2597 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2598 int userId) { 2599 if (!sUserManager.exists(userId)) return null; 2600 PackageSetting ps = mSettings.mPackages.get(packageName); 2601 if (ps != null) { 2602 PackageParser.Package pkg = ps.pkg; 2603 if (pkg == null) { 2604 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2605 return null; 2606 } 2607 // Only data remains, so we aren't worried about code paths 2608 pkg = new PackageParser.Package(packageName); 2609 pkg.applicationInfo.packageName = packageName; 2610 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2611 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 2612 pkg.applicationInfo.dataDir = 2613 getDataPathForPackage(packageName, 0).getPath(); 2614 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2615 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2616 } 2617 return generatePackageInfo(pkg, flags, userId); 2618 } 2619 return null; 2620 } 2621 2622 @Override 2623 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2624 if (!sUserManager.exists(userId)) return null; 2625 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2626 // writer 2627 synchronized (mPackages) { 2628 PackageParser.Package p = mPackages.get(packageName); 2629 if (DEBUG_PACKAGE_INFO) Log.v( 2630 TAG, "getApplicationInfo " + packageName 2631 + ": " + p); 2632 if (p != null) { 2633 PackageSetting ps = mSettings.mPackages.get(packageName); 2634 if (ps == null) return null; 2635 // Note: isEnabledLP() does not apply here - always return info 2636 return PackageParser.generateApplicationInfo( 2637 p, flags, ps.readUserState(userId), userId); 2638 } 2639 if ("android".equals(packageName)||"system".equals(packageName)) { 2640 return mAndroidApplication; 2641 } 2642 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2643 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2644 } 2645 } 2646 return null; 2647 } 2648 2649 2650 @Override 2651 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) { 2652 mContext.enforceCallingOrSelfPermission( 2653 android.Manifest.permission.CLEAR_APP_CACHE, null); 2654 // Queue up an async operation since clearing cache may take a little while. 2655 mHandler.post(new Runnable() { 2656 public void run() { 2657 mHandler.removeCallbacks(this); 2658 int retCode = -1; 2659 synchronized (mInstallLock) { 2660 retCode = mInstaller.freeCache(freeStorageSize); 2661 if (retCode < 0) { 2662 Slog.w(TAG, "Couldn't clear application caches"); 2663 } 2664 } 2665 if (observer != null) { 2666 try { 2667 observer.onRemoveCompleted(null, (retCode >= 0)); 2668 } catch (RemoteException e) { 2669 Slog.w(TAG, "RemoveException when invoking call back"); 2670 } 2671 } 2672 } 2673 }); 2674 } 2675 2676 @Override 2677 public void freeStorage(final long freeStorageSize, final IntentSender pi) { 2678 mContext.enforceCallingOrSelfPermission( 2679 android.Manifest.permission.CLEAR_APP_CACHE, null); 2680 // Queue up an async operation since clearing cache may take a little while. 2681 mHandler.post(new Runnable() { 2682 public void run() { 2683 mHandler.removeCallbacks(this); 2684 int retCode = -1; 2685 synchronized (mInstallLock) { 2686 retCode = mInstaller.freeCache(freeStorageSize); 2687 if (retCode < 0) { 2688 Slog.w(TAG, "Couldn't clear application caches"); 2689 } 2690 } 2691 if(pi != null) { 2692 try { 2693 // Callback via pending intent 2694 int code = (retCode >= 0) ? 1 : 0; 2695 pi.sendIntent(null, code, null, 2696 null, null); 2697 } catch (SendIntentException e1) { 2698 Slog.i(TAG, "Failed to send pending intent"); 2699 } 2700 } 2701 } 2702 }); 2703 } 2704 2705 void freeStorage(long freeStorageSize) throws IOException { 2706 synchronized (mInstallLock) { 2707 if (mInstaller.freeCache(freeStorageSize) < 0) { 2708 throw new IOException("Failed to free enough space"); 2709 } 2710 } 2711 } 2712 2713 @Override 2714 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2715 if (!sUserManager.exists(userId)) return null; 2716 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 2717 synchronized (mPackages) { 2718 PackageParser.Activity a = mActivities.mActivities.get(component); 2719 2720 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2721 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2722 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2723 if (ps == null) return null; 2724 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2725 userId); 2726 } 2727 if (mResolveComponentName.equals(component)) { 2728 return PackageParser.generateActivityInfo(mResolveActivity, flags, 2729 new PackageUserState(), userId); 2730 } 2731 } 2732 return null; 2733 } 2734 2735 @Override 2736 public boolean activitySupportsIntent(ComponentName component, Intent intent, 2737 String resolvedType) { 2738 synchronized (mPackages) { 2739 PackageParser.Activity a = mActivities.mActivities.get(component); 2740 if (a == null) { 2741 return false; 2742 } 2743 for (int i=0; i<a.intents.size(); i++) { 2744 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 2745 intent.getData(), intent.getCategories(), TAG) >= 0) { 2746 return true; 2747 } 2748 } 2749 return false; 2750 } 2751 } 2752 2753 @Override 2754 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2755 if (!sUserManager.exists(userId)) return null; 2756 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 2757 synchronized (mPackages) { 2758 PackageParser.Activity a = mReceivers.mActivities.get(component); 2759 if (DEBUG_PACKAGE_INFO) Log.v( 2760 TAG, "getReceiverInfo " + component + ": " + a); 2761 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2762 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2763 if (ps == null) return null; 2764 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2765 userId); 2766 } 2767 } 2768 return null; 2769 } 2770 2771 @Override 2772 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2773 if (!sUserManager.exists(userId)) return null; 2774 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 2775 synchronized (mPackages) { 2776 PackageParser.Service s = mServices.mServices.get(component); 2777 if (DEBUG_PACKAGE_INFO) Log.v( 2778 TAG, "getServiceInfo " + component + ": " + s); 2779 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2780 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2781 if (ps == null) return null; 2782 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2783 userId); 2784 } 2785 } 2786 return null; 2787 } 2788 2789 @Override 2790 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2791 if (!sUserManager.exists(userId)) return null; 2792 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 2793 synchronized (mPackages) { 2794 PackageParser.Provider p = mProviders.mProviders.get(component); 2795 if (DEBUG_PACKAGE_INFO) Log.v( 2796 TAG, "getProviderInfo " + component + ": " + p); 2797 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2798 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2799 if (ps == null) return null; 2800 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2801 userId); 2802 } 2803 } 2804 return null; 2805 } 2806 2807 @Override 2808 public String[] getSystemSharedLibraryNames() { 2809 Set<String> libSet; 2810 synchronized (mPackages) { 2811 libSet = mSharedLibraries.keySet(); 2812 int size = libSet.size(); 2813 if (size > 0) { 2814 String[] libs = new String[size]; 2815 libSet.toArray(libs); 2816 return libs; 2817 } 2818 } 2819 return null; 2820 } 2821 2822 /** 2823 * @hide 2824 */ 2825 PackageParser.Package findSharedNonSystemLibrary(String libName) { 2826 synchronized (mPackages) { 2827 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 2828 if (lib != null && lib.apk != null) { 2829 return mPackages.get(lib.apk); 2830 } 2831 } 2832 return null; 2833 } 2834 2835 @Override 2836 public FeatureInfo[] getSystemAvailableFeatures() { 2837 Collection<FeatureInfo> featSet; 2838 synchronized (mPackages) { 2839 featSet = mAvailableFeatures.values(); 2840 int size = featSet.size(); 2841 if (size > 0) { 2842 FeatureInfo[] features = new FeatureInfo[size+1]; 2843 featSet.toArray(features); 2844 FeatureInfo fi = new FeatureInfo(); 2845 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2846 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2847 features[size] = fi; 2848 return features; 2849 } 2850 } 2851 return null; 2852 } 2853 2854 @Override 2855 public boolean hasSystemFeature(String name) { 2856 synchronized (mPackages) { 2857 return mAvailableFeatures.containsKey(name); 2858 } 2859 } 2860 2861 private void checkValidCaller(int uid, int userId) { 2862 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2863 return; 2864 2865 throw new SecurityException("Caller uid=" + uid 2866 + " is not privileged to communicate with user=" + userId); 2867 } 2868 2869 @Override 2870 public int checkPermission(String permName, String pkgName, int userId) { 2871 if (!sUserManager.exists(userId)) { 2872 return PackageManager.PERMISSION_DENIED; 2873 } 2874 2875 synchronized (mPackages) { 2876 final PackageParser.Package p = mPackages.get(pkgName); 2877 if (p != null && p.mExtras != null) { 2878 final PackageSetting ps = (PackageSetting) p.mExtras; 2879 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2880 return PackageManager.PERMISSION_GRANTED; 2881 } 2882 } 2883 } 2884 2885 return PackageManager.PERMISSION_DENIED; 2886 } 2887 2888 @Override 2889 public int checkUidPermission(String permName, int uid) { 2890 final int userId = UserHandle.getUserId(uid); 2891 2892 if (!sUserManager.exists(userId)) { 2893 return PackageManager.PERMISSION_DENIED; 2894 } 2895 2896 synchronized (mPackages) { 2897 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2898 if (obj != null) { 2899 final SettingBase ps = (SettingBase) obj; 2900 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2901 return PackageManager.PERMISSION_GRANTED; 2902 } 2903 } else { 2904 ArraySet<String> perms = mSystemPermissions.get(uid); 2905 if (perms != null && perms.contains(permName)) { 2906 return PackageManager.PERMISSION_GRANTED; 2907 } 2908 } 2909 } 2910 2911 return PackageManager.PERMISSION_DENIED; 2912 } 2913 2914 /** 2915 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2916 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2917 * @param checkShell TODO(yamasani): 2918 * @param message the message to log on security exception 2919 */ 2920 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 2921 boolean checkShell, String message) { 2922 if (userId < 0) { 2923 throw new IllegalArgumentException("Invalid userId " + userId); 2924 } 2925 if (checkShell) { 2926 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 2927 } 2928 if (userId == UserHandle.getUserId(callingUid)) return; 2929 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2930 if (requireFullPermission) { 2931 mContext.enforceCallingOrSelfPermission( 2932 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2933 } else { 2934 try { 2935 mContext.enforceCallingOrSelfPermission( 2936 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2937 } catch (SecurityException se) { 2938 mContext.enforceCallingOrSelfPermission( 2939 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2940 } 2941 } 2942 } 2943 } 2944 2945 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 2946 if (callingUid == Process.SHELL_UID) { 2947 if (userHandle >= 0 2948 && sUserManager.hasUserRestriction(restriction, userHandle)) { 2949 throw new SecurityException("Shell does not have permission to access user " 2950 + userHandle); 2951 } else if (userHandle < 0) { 2952 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 2953 + Debug.getCallers(3)); 2954 } 2955 } 2956 } 2957 2958 private BasePermission findPermissionTreeLP(String permName) { 2959 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2960 if (permName.startsWith(bp.name) && 2961 permName.length() > bp.name.length() && 2962 permName.charAt(bp.name.length()) == '.') { 2963 return bp; 2964 } 2965 } 2966 return null; 2967 } 2968 2969 private BasePermission checkPermissionTreeLP(String permName) { 2970 if (permName != null) { 2971 BasePermission bp = findPermissionTreeLP(permName); 2972 if (bp != null) { 2973 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2974 return bp; 2975 } 2976 throw new SecurityException("Calling uid " 2977 + Binder.getCallingUid() 2978 + " is not allowed to add to permission tree " 2979 + bp.name + " owned by uid " + bp.uid); 2980 } 2981 } 2982 throw new SecurityException("No permission tree found for " + permName); 2983 } 2984 2985 static boolean compareStrings(CharSequence s1, CharSequence s2) { 2986 if (s1 == null) { 2987 return s2 == null; 2988 } 2989 if (s2 == null) { 2990 return false; 2991 } 2992 if (s1.getClass() != s2.getClass()) { 2993 return false; 2994 } 2995 return s1.equals(s2); 2996 } 2997 2998 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 2999 if (pi1.icon != pi2.icon) return false; 3000 if (pi1.logo != pi2.logo) return false; 3001 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3002 if (!compareStrings(pi1.name, pi2.name)) return false; 3003 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3004 // We'll take care of setting this one. 3005 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3006 // These are not currently stored in settings. 3007 //if (!compareStrings(pi1.group, pi2.group)) return false; 3008 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3009 //if (pi1.labelRes != pi2.labelRes) return false; 3010 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3011 return true; 3012 } 3013 3014 int permissionInfoFootprint(PermissionInfo info) { 3015 int size = info.name.length(); 3016 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3017 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3018 return size; 3019 } 3020 3021 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3022 int size = 0; 3023 for (BasePermission perm : mSettings.mPermissions.values()) { 3024 if (perm.uid == tree.uid) { 3025 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3026 } 3027 } 3028 return size; 3029 } 3030 3031 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3032 // We calculate the max size of permissions defined by this uid and throw 3033 // if that plus the size of 'info' would exceed our stated maximum. 3034 if (tree.uid != Process.SYSTEM_UID) { 3035 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3036 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3037 throw new SecurityException("Permission tree size cap exceeded"); 3038 } 3039 } 3040 } 3041 3042 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3043 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3044 throw new SecurityException("Label must be specified in permission"); 3045 } 3046 BasePermission tree = checkPermissionTreeLP(info.name); 3047 BasePermission bp = mSettings.mPermissions.get(info.name); 3048 boolean added = bp == null; 3049 boolean changed = true; 3050 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3051 if (added) { 3052 enforcePermissionCapLocked(info, tree); 3053 bp = new BasePermission(info.name, tree.sourcePackage, 3054 BasePermission.TYPE_DYNAMIC); 3055 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3056 throw new SecurityException( 3057 "Not allowed to modify non-dynamic permission " 3058 + info.name); 3059 } else { 3060 if (bp.protectionLevel == fixedLevel 3061 && bp.perm.owner.equals(tree.perm.owner) 3062 && bp.uid == tree.uid 3063 && comparePermissionInfos(bp.perm.info, info)) { 3064 changed = false; 3065 } 3066 } 3067 bp.protectionLevel = fixedLevel; 3068 info = new PermissionInfo(info); 3069 info.protectionLevel = fixedLevel; 3070 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3071 bp.perm.info.packageName = tree.perm.info.packageName; 3072 bp.uid = tree.uid; 3073 if (added) { 3074 mSettings.mPermissions.put(info.name, bp); 3075 } 3076 if (changed) { 3077 if (!async) { 3078 mSettings.writeLPr(); 3079 } else { 3080 scheduleWriteSettingsLocked(); 3081 } 3082 } 3083 return added; 3084 } 3085 3086 @Override 3087 public boolean addPermission(PermissionInfo info) { 3088 synchronized (mPackages) { 3089 return addPermissionLocked(info, false); 3090 } 3091 } 3092 3093 @Override 3094 public boolean addPermissionAsync(PermissionInfo info) { 3095 synchronized (mPackages) { 3096 return addPermissionLocked(info, true); 3097 } 3098 } 3099 3100 @Override 3101 public void removePermission(String name) { 3102 synchronized (mPackages) { 3103 checkPermissionTreeLP(name); 3104 BasePermission bp = mSettings.mPermissions.get(name); 3105 if (bp != null) { 3106 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3107 throw new SecurityException( 3108 "Not allowed to modify non-dynamic permission " 3109 + name); 3110 } 3111 mSettings.mPermissions.remove(name); 3112 mSettings.writeLPr(); 3113 } 3114 } 3115 } 3116 3117 private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg, 3118 BasePermission bp) { 3119 int index = pkg.requestedPermissions.indexOf(bp.name); 3120 if (index == -1) { 3121 throw new SecurityException("Package " + pkg.packageName 3122 + " has not requested permission " + bp.name); 3123 } 3124 if (!bp.isRuntime()) { 3125 throw new SecurityException("Permission " + bp.name 3126 + " is not a changeable permission type"); 3127 } 3128 } 3129 3130 @Override 3131 public boolean grantPermission(String packageName, String name, int userId) { 3132 if (!RUNTIME_PERMISSIONS_ENABLED) { 3133 return false; 3134 } 3135 3136 if (!sUserManager.exists(userId)) { 3137 return false; 3138 } 3139 3140 mContext.enforceCallingOrSelfPermission( 3141 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3142 "grantPermission"); 3143 3144 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3145 "grantPermission"); 3146 3147 boolean gidsChanged = false; 3148 final SettingBase sb; 3149 3150 synchronized (mPackages) { 3151 final PackageParser.Package pkg = mPackages.get(packageName); 3152 if (pkg == null) { 3153 throw new IllegalArgumentException("Unknown package: " + packageName); 3154 } 3155 3156 final BasePermission bp = mSettings.mPermissions.get(name); 3157 if (bp == null) { 3158 throw new IllegalArgumentException("Unknown permission: " + name); 3159 } 3160 3161 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3162 3163 sb = (SettingBase) pkg.mExtras; 3164 if (sb == null) { 3165 throw new IllegalArgumentException("Unknown package: " + packageName); 3166 } 3167 3168 final PermissionsState permissionsState = sb.getPermissionsState(); 3169 3170 final int result = permissionsState.grantRuntimePermission(bp, userId); 3171 switch (result) { 3172 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3173 return false; 3174 } 3175 3176 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3177 gidsChanged = true; 3178 } break; 3179 } 3180 3181 // Not critical if that is lost - app has to request again. 3182 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3183 } 3184 3185 if (gidsChanged) { 3186 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED); 3187 } 3188 3189 return true; 3190 } 3191 3192 @Override 3193 public boolean revokePermission(String packageName, String name, int userId) { 3194 if (!RUNTIME_PERMISSIONS_ENABLED) { 3195 return false; 3196 } 3197 3198 if (!sUserManager.exists(userId)) { 3199 return false; 3200 } 3201 3202 mContext.enforceCallingOrSelfPermission( 3203 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3204 "revokePermission"); 3205 3206 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3207 "revokePermission"); 3208 3209 final SettingBase sb; 3210 3211 synchronized (mPackages) { 3212 final PackageParser.Package pkg = mPackages.get(packageName); 3213 if (pkg == null) { 3214 throw new IllegalArgumentException("Unknown package: " + packageName); 3215 } 3216 3217 final BasePermission bp = mSettings.mPermissions.get(name); 3218 if (bp == null) { 3219 throw new IllegalArgumentException("Unknown permission: " + name); 3220 } 3221 3222 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3223 3224 sb = (SettingBase) pkg.mExtras; 3225 if (sb == null) { 3226 throw new IllegalArgumentException("Unknown package: " + packageName); 3227 } 3228 3229 final PermissionsState permissionsState = sb.getPermissionsState(); 3230 3231 if (permissionsState.revokeRuntimePermission(bp, userId) == 3232 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3233 return false; 3234 } 3235 3236 // Critical, after this call all should never have the permission. 3237 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3238 } 3239 3240 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 3241 3242 return true; 3243 } 3244 3245 @Override 3246 public boolean isProtectedBroadcast(String actionName) { 3247 synchronized (mPackages) { 3248 return mProtectedBroadcasts.contains(actionName); 3249 } 3250 } 3251 3252 @Override 3253 public int checkSignatures(String pkg1, String pkg2) { 3254 synchronized (mPackages) { 3255 final PackageParser.Package p1 = mPackages.get(pkg1); 3256 final PackageParser.Package p2 = mPackages.get(pkg2); 3257 if (p1 == null || p1.mExtras == null 3258 || p2 == null || p2.mExtras == null) { 3259 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3260 } 3261 return compareSignatures(p1.mSignatures, p2.mSignatures); 3262 } 3263 } 3264 3265 @Override 3266 public int checkUidSignatures(int uid1, int uid2) { 3267 // Map to base uids. 3268 uid1 = UserHandle.getAppId(uid1); 3269 uid2 = UserHandle.getAppId(uid2); 3270 // reader 3271 synchronized (mPackages) { 3272 Signature[] s1; 3273 Signature[] s2; 3274 Object obj = mSettings.getUserIdLPr(uid1); 3275 if (obj != null) { 3276 if (obj instanceof SharedUserSetting) { 3277 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 3278 } else if (obj instanceof PackageSetting) { 3279 s1 = ((PackageSetting)obj).signatures.mSignatures; 3280 } else { 3281 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3282 } 3283 } else { 3284 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3285 } 3286 obj = mSettings.getUserIdLPr(uid2); 3287 if (obj != null) { 3288 if (obj instanceof SharedUserSetting) { 3289 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 3290 } else if (obj instanceof PackageSetting) { 3291 s2 = ((PackageSetting)obj).signatures.mSignatures; 3292 } else { 3293 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3294 } 3295 } else { 3296 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3297 } 3298 return compareSignatures(s1, s2); 3299 } 3300 } 3301 3302 private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) { 3303 final long identity = Binder.clearCallingIdentity(); 3304 try { 3305 if (sb instanceof SharedUserSetting) { 3306 SharedUserSetting sus = (SharedUserSetting) sb; 3307 final int packageCount = sus.packages.size(); 3308 for (int i = 0; i < packageCount; i++) { 3309 PackageSetting susPs = sus.packages.valueAt(i); 3310 if (userId == UserHandle.USER_ALL) { 3311 killApplication(susPs.pkg.packageName, susPs.appId, reason); 3312 } else { 3313 final int uid = UserHandle.getUid(userId, susPs.appId); 3314 killUid(uid, reason); 3315 } 3316 } 3317 } else if (sb instanceof PackageSetting) { 3318 PackageSetting ps = (PackageSetting) sb; 3319 if (userId == UserHandle.USER_ALL) { 3320 killApplication(ps.pkg.packageName, ps.appId, reason); 3321 } else { 3322 final int uid = UserHandle.getUid(userId, ps.appId); 3323 killUid(uid, reason); 3324 } 3325 } 3326 } finally { 3327 Binder.restoreCallingIdentity(identity); 3328 } 3329 } 3330 3331 private static void killUid(int uid, String reason) { 3332 IActivityManager am = ActivityManagerNative.getDefault(); 3333 if (am != null) { 3334 try { 3335 am.killUid(uid, reason); 3336 } catch (RemoteException e) { 3337 /* ignore - same process */ 3338 } 3339 } 3340 } 3341 3342 /** 3343 * Compares two sets of signatures. Returns: 3344 * <br /> 3345 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 3346 * <br /> 3347 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 3348 * <br /> 3349 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 3350 * <br /> 3351 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 3352 * <br /> 3353 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 3354 */ 3355 static int compareSignatures(Signature[] s1, Signature[] s2) { 3356 if (s1 == null) { 3357 return s2 == null 3358 ? PackageManager.SIGNATURE_NEITHER_SIGNED 3359 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 3360 } 3361 3362 if (s2 == null) { 3363 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 3364 } 3365 3366 if (s1.length != s2.length) { 3367 return PackageManager.SIGNATURE_NO_MATCH; 3368 } 3369 3370 // Since both signature sets are of size 1, we can compare without HashSets. 3371 if (s1.length == 1) { 3372 return s1[0].equals(s2[0]) ? 3373 PackageManager.SIGNATURE_MATCH : 3374 PackageManager.SIGNATURE_NO_MATCH; 3375 } 3376 3377 ArraySet<Signature> set1 = new ArraySet<Signature>(); 3378 for (Signature sig : s1) { 3379 set1.add(sig); 3380 } 3381 ArraySet<Signature> set2 = new ArraySet<Signature>(); 3382 for (Signature sig : s2) { 3383 set2.add(sig); 3384 } 3385 // Make sure s2 contains all signatures in s1. 3386 if (set1.equals(set2)) { 3387 return PackageManager.SIGNATURE_MATCH; 3388 } 3389 return PackageManager.SIGNATURE_NO_MATCH; 3390 } 3391 3392 /** 3393 * If the database version for this type of package (internal storage or 3394 * external storage) is less than the version where package signatures 3395 * were updated, return true. 3396 */ 3397 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3398 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan( 3399 DatabaseVersion.SIGNATURE_END_ENTITY)) 3400 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan( 3401 DatabaseVersion.SIGNATURE_END_ENTITY)); 3402 } 3403 3404 /** 3405 * Used for backward compatibility to make sure any packages with 3406 * certificate chains get upgraded to the new style. {@code existingSigs} 3407 * will be in the old format (since they were stored on disk from before the 3408 * system upgrade) and {@code scannedSigs} will be in the newer format. 3409 */ 3410 private int compareSignaturesCompat(PackageSignatures existingSigs, 3411 PackageParser.Package scannedPkg) { 3412 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 3413 return PackageManager.SIGNATURE_NO_MATCH; 3414 } 3415 3416 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 3417 for (Signature sig : existingSigs.mSignatures) { 3418 existingSet.add(sig); 3419 } 3420 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 3421 for (Signature sig : scannedPkg.mSignatures) { 3422 try { 3423 Signature[] chainSignatures = sig.getChainSignatures(); 3424 for (Signature chainSig : chainSignatures) { 3425 scannedCompatSet.add(chainSig); 3426 } 3427 } catch (CertificateEncodingException e) { 3428 scannedCompatSet.add(sig); 3429 } 3430 } 3431 /* 3432 * Make sure the expanded scanned set contains all signatures in the 3433 * existing one. 3434 */ 3435 if (scannedCompatSet.equals(existingSet)) { 3436 // Migrate the old signatures to the new scheme. 3437 existingSigs.assignSignatures(scannedPkg.mSignatures); 3438 // The new KeySets will be re-added later in the scanning process. 3439 synchronized (mPackages) { 3440 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 3441 } 3442 return PackageManager.SIGNATURE_MATCH; 3443 } 3444 return PackageManager.SIGNATURE_NO_MATCH; 3445 } 3446 3447 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3448 if (isExternal(scannedPkg)) { 3449 return mSettings.isExternalDatabaseVersionOlderThan( 3450 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3451 } else { 3452 return mSettings.isInternalDatabaseVersionOlderThan( 3453 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3454 } 3455 } 3456 3457 private int compareSignaturesRecover(PackageSignatures existingSigs, 3458 PackageParser.Package scannedPkg) { 3459 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 3460 return PackageManager.SIGNATURE_NO_MATCH; 3461 } 3462 3463 String msg = null; 3464 try { 3465 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 3466 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 3467 + scannedPkg.packageName); 3468 return PackageManager.SIGNATURE_MATCH; 3469 } 3470 } catch (CertificateException e) { 3471 msg = e.getMessage(); 3472 } 3473 3474 logCriticalInfo(Log.INFO, 3475 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 3476 return PackageManager.SIGNATURE_NO_MATCH; 3477 } 3478 3479 @Override 3480 public String[] getPackagesForUid(int uid) { 3481 uid = UserHandle.getAppId(uid); 3482 // reader 3483 synchronized (mPackages) { 3484 Object obj = mSettings.getUserIdLPr(uid); 3485 if (obj instanceof SharedUserSetting) { 3486 final SharedUserSetting sus = (SharedUserSetting) obj; 3487 final int N = sus.packages.size(); 3488 final String[] res = new String[N]; 3489 final Iterator<PackageSetting> it = sus.packages.iterator(); 3490 int i = 0; 3491 while (it.hasNext()) { 3492 res[i++] = it.next().name; 3493 } 3494 return res; 3495 } else if (obj instanceof PackageSetting) { 3496 final PackageSetting ps = (PackageSetting) obj; 3497 return new String[] { ps.name }; 3498 } 3499 } 3500 return null; 3501 } 3502 3503 @Override 3504 public String getNameForUid(int uid) { 3505 // reader 3506 synchronized (mPackages) { 3507 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3508 if (obj instanceof SharedUserSetting) { 3509 final SharedUserSetting sus = (SharedUserSetting) obj; 3510 return sus.name + ":" + sus.userId; 3511 } else if (obj instanceof PackageSetting) { 3512 final PackageSetting ps = (PackageSetting) obj; 3513 return ps.name; 3514 } 3515 } 3516 return null; 3517 } 3518 3519 @Override 3520 public int getUidForSharedUser(String sharedUserName) { 3521 if(sharedUserName == null) { 3522 return -1; 3523 } 3524 // reader 3525 synchronized (mPackages) { 3526 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 3527 if (suid == null) { 3528 return -1; 3529 } 3530 return suid.userId; 3531 } 3532 } 3533 3534 @Override 3535 public int getFlagsForUid(int uid) { 3536 synchronized (mPackages) { 3537 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3538 if (obj instanceof SharedUserSetting) { 3539 final SharedUserSetting sus = (SharedUserSetting) obj; 3540 return sus.pkgFlags; 3541 } else if (obj instanceof PackageSetting) { 3542 final PackageSetting ps = (PackageSetting) obj; 3543 return ps.pkgFlags; 3544 } 3545 } 3546 return 0; 3547 } 3548 3549 @Override 3550 public int getPrivateFlagsForUid(int uid) { 3551 synchronized (mPackages) { 3552 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3553 if (obj instanceof SharedUserSetting) { 3554 final SharedUserSetting sus = (SharedUserSetting) obj; 3555 return sus.pkgPrivateFlags; 3556 } else if (obj instanceof PackageSetting) { 3557 final PackageSetting ps = (PackageSetting) obj; 3558 return ps.pkgPrivateFlags; 3559 } 3560 } 3561 return 0; 3562 } 3563 3564 @Override 3565 public boolean isUidPrivileged(int uid) { 3566 uid = UserHandle.getAppId(uid); 3567 // reader 3568 synchronized (mPackages) { 3569 Object obj = mSettings.getUserIdLPr(uid); 3570 if (obj instanceof SharedUserSetting) { 3571 final SharedUserSetting sus = (SharedUserSetting) obj; 3572 final Iterator<PackageSetting> it = sus.packages.iterator(); 3573 while (it.hasNext()) { 3574 if (it.next().isPrivileged()) { 3575 return true; 3576 } 3577 } 3578 } else if (obj instanceof PackageSetting) { 3579 final PackageSetting ps = (PackageSetting) obj; 3580 return ps.isPrivileged(); 3581 } 3582 } 3583 return false; 3584 } 3585 3586 @Override 3587 public String[] getAppOpPermissionPackages(String permissionName) { 3588 synchronized (mPackages) { 3589 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 3590 if (pkgs == null) { 3591 return null; 3592 } 3593 return pkgs.toArray(new String[pkgs.size()]); 3594 } 3595 } 3596 3597 @Override 3598 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 3599 int flags, int userId) { 3600 if (!sUserManager.exists(userId)) return null; 3601 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 3602 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3603 return chooseBestActivity(intent, resolvedType, flags, query, userId); 3604 } 3605 3606 @Override 3607 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 3608 IntentFilter filter, int match, ComponentName activity) { 3609 final int userId = UserHandle.getCallingUserId(); 3610 if (DEBUG_PREFERRED) { 3611 Log.v(TAG, "setLastChosenActivity intent=" + intent 3612 + " resolvedType=" + resolvedType 3613 + " flags=" + flags 3614 + " filter=" + filter 3615 + " match=" + match 3616 + " activity=" + activity); 3617 filter.dump(new PrintStreamPrinter(System.out), " "); 3618 } 3619 intent.setComponent(null); 3620 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3621 // Find any earlier preferred or last chosen entries and nuke them 3622 findPreferredActivity(intent, resolvedType, 3623 flags, query, 0, false, true, false, userId); 3624 // Add the new activity as the last chosen for this filter 3625 addPreferredActivityInternal(filter, match, null, activity, false, userId, 3626 "Setting last chosen"); 3627 } 3628 3629 @Override 3630 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 3631 final int userId = UserHandle.getCallingUserId(); 3632 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 3633 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3634 return findPreferredActivity(intent, resolvedType, flags, query, 0, 3635 false, false, false, userId); 3636 } 3637 3638 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 3639 int flags, List<ResolveInfo> query, int userId) { 3640 if (query != null) { 3641 final int N = query.size(); 3642 if (N == 1) { 3643 return query.get(0); 3644 } else if (N > 1) { 3645 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3646 // If there is more than one activity with the same priority, 3647 // then let the user decide between them. 3648 ResolveInfo r0 = query.get(0); 3649 ResolveInfo r1 = query.get(1); 3650 if (DEBUG_INTENT_MATCHING || debug) { 3651 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 3652 + r1.activityInfo.name + "=" + r1.priority); 3653 } 3654 // If the first activity has a higher priority, or a different 3655 // default, then it is always desireable to pick it. 3656 if (r0.priority != r1.priority 3657 || r0.preferredOrder != r1.preferredOrder 3658 || r0.isDefault != r1.isDefault) { 3659 return query.get(0); 3660 } 3661 // If we have saved a preference for a preferred activity for 3662 // this Intent, use that. 3663 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 3664 flags, query, r0.priority, true, false, debug, userId); 3665 if (ri != null) { 3666 return ri; 3667 } 3668 if (userId != 0) { 3669 ri = new ResolveInfo(mResolveInfo); 3670 ri.activityInfo = new ActivityInfo(ri.activityInfo); 3671 ri.activityInfo.applicationInfo = new ApplicationInfo( 3672 ri.activityInfo.applicationInfo); 3673 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 3674 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 3675 return ri; 3676 } 3677 return mResolveInfo; 3678 } 3679 } 3680 return null; 3681 } 3682 3683 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 3684 int flags, List<ResolveInfo> query, boolean debug, int userId) { 3685 final int N = query.size(); 3686 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 3687 .get(userId); 3688 // Get the list of persistent preferred activities that handle the intent 3689 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 3690 List<PersistentPreferredActivity> pprefs = ppir != null 3691 ? ppir.queryIntent(intent, resolvedType, 3692 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3693 : null; 3694 if (pprefs != null && pprefs.size() > 0) { 3695 final int M = pprefs.size(); 3696 for (int i=0; i<M; i++) { 3697 final PersistentPreferredActivity ppa = pprefs.get(i); 3698 if (DEBUG_PREFERRED || debug) { 3699 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 3700 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 3701 + "\n component=" + ppa.mComponent); 3702 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3703 } 3704 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 3705 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3706 if (DEBUG_PREFERRED || debug) { 3707 Slog.v(TAG, "Found persistent preferred activity:"); 3708 if (ai != null) { 3709 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3710 } else { 3711 Slog.v(TAG, " null"); 3712 } 3713 } 3714 if (ai == null) { 3715 // This previously registered persistent preferred activity 3716 // component is no longer known. Ignore it and do NOT remove it. 3717 continue; 3718 } 3719 for (int j=0; j<N; j++) { 3720 final ResolveInfo ri = query.get(j); 3721 if (!ri.activityInfo.applicationInfo.packageName 3722 .equals(ai.applicationInfo.packageName)) { 3723 continue; 3724 } 3725 if (!ri.activityInfo.name.equals(ai.name)) { 3726 continue; 3727 } 3728 // Found a persistent preference that can handle the intent. 3729 if (DEBUG_PREFERRED || debug) { 3730 Slog.v(TAG, "Returning persistent preferred activity: " + 3731 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3732 } 3733 return ri; 3734 } 3735 } 3736 } 3737 return null; 3738 } 3739 3740 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 3741 List<ResolveInfo> query, int priority, boolean always, 3742 boolean removeMatches, boolean debug, int userId) { 3743 if (!sUserManager.exists(userId)) return null; 3744 // writer 3745 synchronized (mPackages) { 3746 if (intent.getSelector() != null) { 3747 intent = intent.getSelector(); 3748 } 3749 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3750 3751 // Try to find a matching persistent preferred activity. 3752 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 3753 debug, userId); 3754 3755 // If a persistent preferred activity matched, use it. 3756 if (pri != null) { 3757 return pri; 3758 } 3759 3760 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 3761 // Get the list of preferred activities that handle the intent 3762 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 3763 List<PreferredActivity> prefs = pir != null 3764 ? pir.queryIntent(intent, resolvedType, 3765 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3766 : null; 3767 if (prefs != null && prefs.size() > 0) { 3768 boolean changed = false; 3769 try { 3770 // First figure out how good the original match set is. 3771 // We will only allow preferred activities that came 3772 // from the same match quality. 3773 int match = 0; 3774 3775 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 3776 3777 final int N = query.size(); 3778 for (int j=0; j<N; j++) { 3779 final ResolveInfo ri = query.get(j); 3780 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 3781 + ": 0x" + Integer.toHexString(match)); 3782 if (ri.match > match) { 3783 match = ri.match; 3784 } 3785 } 3786 3787 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 3788 + Integer.toHexString(match)); 3789 3790 match &= IntentFilter.MATCH_CATEGORY_MASK; 3791 final int M = prefs.size(); 3792 for (int i=0; i<M; i++) { 3793 final PreferredActivity pa = prefs.get(i); 3794 if (DEBUG_PREFERRED || debug) { 3795 Slog.v(TAG, "Checking PreferredActivity ds=" 3796 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 3797 + "\n component=" + pa.mPref.mComponent); 3798 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3799 } 3800 if (pa.mPref.mMatch != match) { 3801 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 3802 + Integer.toHexString(pa.mPref.mMatch)); 3803 continue; 3804 } 3805 // If it's not an "always" type preferred activity and that's what we're 3806 // looking for, skip it. 3807 if (always && !pa.mPref.mAlways) { 3808 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 3809 continue; 3810 } 3811 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 3812 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3813 if (DEBUG_PREFERRED || debug) { 3814 Slog.v(TAG, "Found preferred activity:"); 3815 if (ai != null) { 3816 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3817 } else { 3818 Slog.v(TAG, " null"); 3819 } 3820 } 3821 if (ai == null) { 3822 // This previously registered preferred activity 3823 // component is no longer known. Most likely an update 3824 // to the app was installed and in the new version this 3825 // component no longer exists. Clean it up by removing 3826 // it from the preferred activities list, and skip it. 3827 Slog.w(TAG, "Removing dangling preferred activity: " 3828 + pa.mPref.mComponent); 3829 pir.removeFilter(pa); 3830 changed = true; 3831 continue; 3832 } 3833 for (int j=0; j<N; j++) { 3834 final ResolveInfo ri = query.get(j); 3835 if (!ri.activityInfo.applicationInfo.packageName 3836 .equals(ai.applicationInfo.packageName)) { 3837 continue; 3838 } 3839 if (!ri.activityInfo.name.equals(ai.name)) { 3840 continue; 3841 } 3842 3843 if (removeMatches) { 3844 pir.removeFilter(pa); 3845 changed = true; 3846 if (DEBUG_PREFERRED) { 3847 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 3848 } 3849 break; 3850 } 3851 3852 // Okay we found a previously set preferred or last chosen app. 3853 // If the result set is different from when this 3854 // was created, we need to clear it and re-ask the 3855 // user their preference, if we're looking for an "always" type entry. 3856 if (always && !pa.mPref.sameSet(query)) { 3857 Slog.i(TAG, "Result set changed, dropping preferred activity for " 3858 + intent + " type " + resolvedType); 3859 if (DEBUG_PREFERRED) { 3860 Slog.v(TAG, "Removing preferred activity since set changed " 3861 + pa.mPref.mComponent); 3862 } 3863 pir.removeFilter(pa); 3864 // Re-add the filter as a "last chosen" entry (!always) 3865 PreferredActivity lastChosen = new PreferredActivity( 3866 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 3867 pir.addFilter(lastChosen); 3868 changed = true; 3869 return null; 3870 } 3871 3872 // Yay! Either the set matched or we're looking for the last chosen 3873 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 3874 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3875 return ri; 3876 } 3877 } 3878 } finally { 3879 if (changed) { 3880 if (DEBUG_PREFERRED) { 3881 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 3882 } 3883 scheduleWritePackageRestrictionsLocked(userId); 3884 } 3885 } 3886 } 3887 } 3888 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 3889 return null; 3890 } 3891 3892 /* 3893 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 3894 */ 3895 @Override 3896 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 3897 int targetUserId) { 3898 mContext.enforceCallingOrSelfPermission( 3899 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 3900 List<CrossProfileIntentFilter> matches = 3901 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 3902 if (matches != null) { 3903 int size = matches.size(); 3904 for (int i = 0; i < size; i++) { 3905 if (matches.get(i).getTargetUserId() == targetUserId) return true; 3906 } 3907 } 3908 return false; 3909 } 3910 3911 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 3912 String resolvedType, int userId) { 3913 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 3914 if (resolver != null) { 3915 return resolver.queryIntent(intent, resolvedType, false, userId); 3916 } 3917 return null; 3918 } 3919 3920 @Override 3921 public List<ResolveInfo> queryIntentActivities(Intent intent, 3922 String resolvedType, int flags, int userId) { 3923 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3924 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 3925 ComponentName comp = intent.getComponent(); 3926 if (comp == null) { 3927 if (intent.getSelector() != null) { 3928 intent = intent.getSelector(); 3929 comp = intent.getComponent(); 3930 } 3931 } 3932 3933 if (comp != null) { 3934 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3935 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 3936 if (ai != null) { 3937 final ResolveInfo ri = new ResolveInfo(); 3938 ri.activityInfo = ai; 3939 list.add(ri); 3940 } 3941 return list; 3942 } 3943 3944 // reader 3945 synchronized (mPackages) { 3946 final String pkgName = intent.getPackage(); 3947 if (pkgName == null) { 3948 List<CrossProfileIntentFilter> matchingFilters = 3949 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 3950 // Check for results that need to skip the current profile. 3951 ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 3952 resolvedType, flags, userId); 3953 if (resolveInfo != null) { 3954 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 3955 result.add(resolveInfo); 3956 return filterIfNotPrimaryUser(result, userId); 3957 } 3958 // Check for cross profile results. 3959 resolveInfo = queryCrossProfileIntents( 3960 matchingFilters, intent, resolvedType, flags, userId); 3961 3962 // Check for results in the current profile. 3963 List<ResolveInfo> result = mActivities.queryIntent( 3964 intent, resolvedType, flags, userId); 3965 if (resolveInfo != null) { 3966 result.add(resolveInfo); 3967 Collections.sort(result, mResolvePrioritySorter); 3968 } 3969 result = filterIfNotPrimaryUser(result, userId); 3970 if (result.size() > 1) { 3971 return filterCandidatesWithDomainPreferedActivitiesLPr(result); 3972 } 3973 3974 return result; 3975 } 3976 final PackageParser.Package pkg = mPackages.get(pkgName); 3977 if (pkg != null) { 3978 return filterIfNotPrimaryUser( 3979 mActivities.queryIntentForPackage( 3980 intent, resolvedType, flags, pkg.activities, userId), 3981 userId); 3982 } 3983 return new ArrayList<ResolveInfo>(); 3984 } 3985 } 3986 3987 /** 3988 * Filter out activities with primaryUserOnly flag set, when current user is not the owner. 3989 * 3990 * @return filtered list 3991 */ 3992 private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) { 3993 if (userId == UserHandle.USER_OWNER) { 3994 return resolveInfos; 3995 } 3996 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 3997 ResolveInfo info = resolveInfos.get(i); 3998 if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 3999 resolveInfos.remove(i); 4000 } 4001 } 4002 return resolveInfos; 4003 } 4004 4005 private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr( 4006 List<ResolveInfo> candidates) { 4007 if (DEBUG_PREFERRED) { 4008 Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " + 4009 candidates.size()); 4010 } 4011 final int userId = UserHandle.getCallingUserId(); 4012 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 4013 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 4014 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 4015 synchronized (mPackages) { 4016 final int count = candidates.size(); 4017 // First, try to use the domain prefered App 4018 for (int n=0; n<count; n++) { 4019 ResolveInfo info = candidates.get(n); 4020 String packageName = info.activityInfo.packageName; 4021 PackageSetting ps = mSettings.mPackages.get(packageName); 4022 if (ps != null) { 4023 // Try to get the status from User settings first 4024 int status = getDomainVerificationStatusLPr(ps, userId); 4025 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS || 4026 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4027 result.add(info); 4028 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4029 neverList.add(info); 4030 } 4031 // Add to the special match all list (Browser use case) 4032 if (info.handleAllWebDataURI) { 4033 matchAllList.add(info); 4034 } 4035 } 4036 } 4037 // If there is nothing selected, add all candidates and remove the ones that the User 4038 // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and 4039 // also remove any . 4040 // If there is still none after this pass, add all Browser Apps and let the User decide 4041 // with the Disambiguation dialog if there are several ones. 4042 if (result.size() == 0) { 4043 result.addAll(candidates); 4044 } 4045 result.removeAll(neverList); 4046 result.removeAll(matchAllList); 4047 if (result.size() == 0) { 4048 result.addAll(matchAllList); 4049 } 4050 } 4051 if (DEBUG_PREFERRED) { 4052 Slog.v("TAG", "Filtered results with prefered activities. New candidates count: " + 4053 result.size()); 4054 } 4055 return result; 4056 } 4057 4058 private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 4059 int status = ps.getDomainVerificationStatusForUser(userId); 4060 // if none available, get the master status 4061 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4062 if (ps.getIntentFilterVerificationInfo() != null) { 4063 status = ps.getIntentFilterVerificationInfo().getStatus(); 4064 } 4065 } 4066 return status; 4067 } 4068 4069 private ResolveInfo querySkipCurrentProfileIntents( 4070 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4071 int flags, int sourceUserId) { 4072 if (matchingFilters != null) { 4073 int size = matchingFilters.size(); 4074 for (int i = 0; i < size; i ++) { 4075 CrossProfileIntentFilter filter = matchingFilters.get(i); 4076 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 4077 // Checking if there are activities in the target user that can handle the 4078 // intent. 4079 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4080 flags, sourceUserId); 4081 if (resolveInfo != null) { 4082 return resolveInfo; 4083 } 4084 } 4085 } 4086 } 4087 return null; 4088 } 4089 4090 // Return matching ResolveInfo if any for skip current profile intent filters. 4091 private ResolveInfo queryCrossProfileIntents( 4092 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4093 int flags, int sourceUserId) { 4094 if (matchingFilters != null) { 4095 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 4096 // match the same intent. For performance reasons, it is better not to 4097 // run queryIntent twice for the same userId 4098 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 4099 int size = matchingFilters.size(); 4100 for (int i = 0; i < size; i++) { 4101 CrossProfileIntentFilter filter = matchingFilters.get(i); 4102 int targetUserId = filter.getTargetUserId(); 4103 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 4104 && !alreadyTriedUserIds.get(targetUserId)) { 4105 // Checking if there are activities in the target user that can handle the 4106 // intent. 4107 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4108 flags, sourceUserId); 4109 if (resolveInfo != null) return resolveInfo; 4110 alreadyTriedUserIds.put(targetUserId, true); 4111 } 4112 } 4113 } 4114 return null; 4115 } 4116 4117 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 4118 String resolvedType, int flags, int sourceUserId) { 4119 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4120 resolvedType, flags, filter.getTargetUserId()); 4121 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 4122 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 4123 } 4124 return null; 4125 } 4126 4127 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 4128 int sourceUserId, int targetUserId) { 4129 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 4130 String className; 4131 if (targetUserId == UserHandle.USER_OWNER) { 4132 className = FORWARD_INTENT_TO_USER_OWNER; 4133 } else { 4134 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 4135 } 4136 ComponentName forwardingActivityComponentName = new ComponentName( 4137 mAndroidApplication.packageName, className); 4138 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 4139 sourceUserId); 4140 if (targetUserId == UserHandle.USER_OWNER) { 4141 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 4142 forwardingResolveInfo.noResourceId = true; 4143 } 4144 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 4145 forwardingResolveInfo.priority = 0; 4146 forwardingResolveInfo.preferredOrder = 0; 4147 forwardingResolveInfo.match = 0; 4148 forwardingResolveInfo.isDefault = true; 4149 forwardingResolveInfo.filter = filter; 4150 forwardingResolveInfo.targetUserId = targetUserId; 4151 return forwardingResolveInfo; 4152 } 4153 4154 @Override 4155 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 4156 Intent[] specifics, String[] specificTypes, Intent intent, 4157 String resolvedType, int flags, int userId) { 4158 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4159 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 4160 false, "query intent activity options"); 4161 final String resultsAction = intent.getAction(); 4162 4163 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 4164 | PackageManager.GET_RESOLVED_FILTER, userId); 4165 4166 if (DEBUG_INTENT_MATCHING) { 4167 Log.v(TAG, "Query " + intent + ": " + results); 4168 } 4169 4170 int specificsPos = 0; 4171 int N; 4172 4173 // todo: note that the algorithm used here is O(N^2). This 4174 // isn't a problem in our current environment, but if we start running 4175 // into situations where we have more than 5 or 10 matches then this 4176 // should probably be changed to something smarter... 4177 4178 // First we go through and resolve each of the specific items 4179 // that were supplied, taking care of removing any corresponding 4180 // duplicate items in the generic resolve list. 4181 if (specifics != null) { 4182 for (int i=0; i<specifics.length; i++) { 4183 final Intent sintent = specifics[i]; 4184 if (sintent == null) { 4185 continue; 4186 } 4187 4188 if (DEBUG_INTENT_MATCHING) { 4189 Log.v(TAG, "Specific #" + i + ": " + sintent); 4190 } 4191 4192 String action = sintent.getAction(); 4193 if (resultsAction != null && resultsAction.equals(action)) { 4194 // If this action was explicitly requested, then don't 4195 // remove things that have it. 4196 action = null; 4197 } 4198 4199 ResolveInfo ri = null; 4200 ActivityInfo ai = null; 4201 4202 ComponentName comp = sintent.getComponent(); 4203 if (comp == null) { 4204 ri = resolveIntent( 4205 sintent, 4206 specificTypes != null ? specificTypes[i] : null, 4207 flags, userId); 4208 if (ri == null) { 4209 continue; 4210 } 4211 if (ri == mResolveInfo) { 4212 // ACK! Must do something better with this. 4213 } 4214 ai = ri.activityInfo; 4215 comp = new ComponentName(ai.applicationInfo.packageName, 4216 ai.name); 4217 } else { 4218 ai = getActivityInfo(comp, flags, userId); 4219 if (ai == null) { 4220 continue; 4221 } 4222 } 4223 4224 // Look for any generic query activities that are duplicates 4225 // of this specific one, and remove them from the results. 4226 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 4227 N = results.size(); 4228 int j; 4229 for (j=specificsPos; j<N; j++) { 4230 ResolveInfo sri = results.get(j); 4231 if ((sri.activityInfo.name.equals(comp.getClassName()) 4232 && sri.activityInfo.applicationInfo.packageName.equals( 4233 comp.getPackageName())) 4234 || (action != null && sri.filter.matchAction(action))) { 4235 results.remove(j); 4236 if (DEBUG_INTENT_MATCHING) Log.v( 4237 TAG, "Removing duplicate item from " + j 4238 + " due to specific " + specificsPos); 4239 if (ri == null) { 4240 ri = sri; 4241 } 4242 j--; 4243 N--; 4244 } 4245 } 4246 4247 // Add this specific item to its proper place. 4248 if (ri == null) { 4249 ri = new ResolveInfo(); 4250 ri.activityInfo = ai; 4251 } 4252 results.add(specificsPos, ri); 4253 ri.specificIndex = i; 4254 specificsPos++; 4255 } 4256 } 4257 4258 // Now we go through the remaining generic results and remove any 4259 // duplicate actions that are found here. 4260 N = results.size(); 4261 for (int i=specificsPos; i<N-1; i++) { 4262 final ResolveInfo rii = results.get(i); 4263 if (rii.filter == null) { 4264 continue; 4265 } 4266 4267 // Iterate over all of the actions of this result's intent 4268 // filter... typically this should be just one. 4269 final Iterator<String> it = rii.filter.actionsIterator(); 4270 if (it == null) { 4271 continue; 4272 } 4273 while (it.hasNext()) { 4274 final String action = it.next(); 4275 if (resultsAction != null && resultsAction.equals(action)) { 4276 // If this action was explicitly requested, then don't 4277 // remove things that have it. 4278 continue; 4279 } 4280 for (int j=i+1; j<N; j++) { 4281 final ResolveInfo rij = results.get(j); 4282 if (rij.filter != null && rij.filter.hasAction(action)) { 4283 results.remove(j); 4284 if (DEBUG_INTENT_MATCHING) Log.v( 4285 TAG, "Removing duplicate item from " + j 4286 + " due to action " + action + " at " + i); 4287 j--; 4288 N--; 4289 } 4290 } 4291 } 4292 4293 // If the caller didn't request filter information, drop it now 4294 // so we don't have to marshall/unmarshall it. 4295 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4296 rii.filter = null; 4297 } 4298 } 4299 4300 // Filter out the caller activity if so requested. 4301 if (caller != null) { 4302 N = results.size(); 4303 for (int i=0; i<N; i++) { 4304 ActivityInfo ainfo = results.get(i).activityInfo; 4305 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 4306 && caller.getClassName().equals(ainfo.name)) { 4307 results.remove(i); 4308 break; 4309 } 4310 } 4311 } 4312 4313 // If the caller didn't request filter information, 4314 // drop them now so we don't have to 4315 // marshall/unmarshall it. 4316 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4317 N = results.size(); 4318 for (int i=0; i<N; i++) { 4319 results.get(i).filter = null; 4320 } 4321 } 4322 4323 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 4324 return results; 4325 } 4326 4327 @Override 4328 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 4329 int userId) { 4330 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4331 ComponentName comp = intent.getComponent(); 4332 if (comp == null) { 4333 if (intent.getSelector() != null) { 4334 intent = intent.getSelector(); 4335 comp = intent.getComponent(); 4336 } 4337 } 4338 if (comp != null) { 4339 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4340 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 4341 if (ai != null) { 4342 ResolveInfo ri = new ResolveInfo(); 4343 ri.activityInfo = ai; 4344 list.add(ri); 4345 } 4346 return list; 4347 } 4348 4349 // reader 4350 synchronized (mPackages) { 4351 String pkgName = intent.getPackage(); 4352 if (pkgName == null) { 4353 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 4354 } 4355 final PackageParser.Package pkg = mPackages.get(pkgName); 4356 if (pkg != null) { 4357 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 4358 userId); 4359 } 4360 return null; 4361 } 4362 } 4363 4364 @Override 4365 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 4366 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 4367 if (!sUserManager.exists(userId)) return null; 4368 if (query != null) { 4369 if (query.size() >= 1) { 4370 // If there is more than one service with the same priority, 4371 // just arbitrarily pick the first one. 4372 return query.get(0); 4373 } 4374 } 4375 return null; 4376 } 4377 4378 @Override 4379 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 4380 int userId) { 4381 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4382 ComponentName comp = intent.getComponent(); 4383 if (comp == null) { 4384 if (intent.getSelector() != null) { 4385 intent = intent.getSelector(); 4386 comp = intent.getComponent(); 4387 } 4388 } 4389 if (comp != null) { 4390 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4391 final ServiceInfo si = getServiceInfo(comp, flags, userId); 4392 if (si != null) { 4393 final ResolveInfo ri = new ResolveInfo(); 4394 ri.serviceInfo = si; 4395 list.add(ri); 4396 } 4397 return list; 4398 } 4399 4400 // reader 4401 synchronized (mPackages) { 4402 String pkgName = intent.getPackage(); 4403 if (pkgName == null) { 4404 return mServices.queryIntent(intent, resolvedType, flags, userId); 4405 } 4406 final PackageParser.Package pkg = mPackages.get(pkgName); 4407 if (pkg != null) { 4408 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 4409 userId); 4410 } 4411 return null; 4412 } 4413 } 4414 4415 @Override 4416 public List<ResolveInfo> queryIntentContentProviders( 4417 Intent intent, String resolvedType, int flags, int userId) { 4418 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4419 ComponentName comp = intent.getComponent(); 4420 if (comp == null) { 4421 if (intent.getSelector() != null) { 4422 intent = intent.getSelector(); 4423 comp = intent.getComponent(); 4424 } 4425 } 4426 if (comp != null) { 4427 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4428 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 4429 if (pi != null) { 4430 final ResolveInfo ri = new ResolveInfo(); 4431 ri.providerInfo = pi; 4432 list.add(ri); 4433 } 4434 return list; 4435 } 4436 4437 // reader 4438 synchronized (mPackages) { 4439 String pkgName = intent.getPackage(); 4440 if (pkgName == null) { 4441 return mProviders.queryIntent(intent, resolvedType, flags, userId); 4442 } 4443 final PackageParser.Package pkg = mPackages.get(pkgName); 4444 if (pkg != null) { 4445 return mProviders.queryIntentForPackage( 4446 intent, resolvedType, flags, pkg.providers, userId); 4447 } 4448 return null; 4449 } 4450 } 4451 4452 @Override 4453 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 4454 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4455 4456 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 4457 4458 // writer 4459 synchronized (mPackages) { 4460 ArrayList<PackageInfo> list; 4461 if (listUninstalled) { 4462 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 4463 for (PackageSetting ps : mSettings.mPackages.values()) { 4464 PackageInfo pi; 4465 if (ps.pkg != null) { 4466 pi = generatePackageInfo(ps.pkg, flags, userId); 4467 } else { 4468 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4469 } 4470 if (pi != null) { 4471 list.add(pi); 4472 } 4473 } 4474 } else { 4475 list = new ArrayList<PackageInfo>(mPackages.size()); 4476 for (PackageParser.Package p : mPackages.values()) { 4477 PackageInfo pi = generatePackageInfo(p, flags, userId); 4478 if (pi != null) { 4479 list.add(pi); 4480 } 4481 } 4482 } 4483 4484 return new ParceledListSlice<PackageInfo>(list); 4485 } 4486 } 4487 4488 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 4489 String[] permissions, boolean[] tmp, int flags, int userId) { 4490 int numMatch = 0; 4491 final PermissionsState permissionsState = ps.getPermissionsState(); 4492 for (int i=0; i<permissions.length; i++) { 4493 final String permission = permissions[i]; 4494 if (permissionsState.hasPermission(permission, userId)) { 4495 tmp[i] = true; 4496 numMatch++; 4497 } else { 4498 tmp[i] = false; 4499 } 4500 } 4501 if (numMatch == 0) { 4502 return; 4503 } 4504 PackageInfo pi; 4505 if (ps.pkg != null) { 4506 pi = generatePackageInfo(ps.pkg, flags, userId); 4507 } else { 4508 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4509 } 4510 // The above might return null in cases of uninstalled apps or install-state 4511 // skew across users/profiles. 4512 if (pi != null) { 4513 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 4514 if (numMatch == permissions.length) { 4515 pi.requestedPermissions = permissions; 4516 } else { 4517 pi.requestedPermissions = new String[numMatch]; 4518 numMatch = 0; 4519 for (int i=0; i<permissions.length; i++) { 4520 if (tmp[i]) { 4521 pi.requestedPermissions[numMatch] = permissions[i]; 4522 numMatch++; 4523 } 4524 } 4525 } 4526 } 4527 list.add(pi); 4528 } 4529 } 4530 4531 @Override 4532 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 4533 String[] permissions, int flags, int userId) { 4534 if (!sUserManager.exists(userId)) return null; 4535 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4536 4537 // writer 4538 synchronized (mPackages) { 4539 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 4540 boolean[] tmpBools = new boolean[permissions.length]; 4541 if (listUninstalled) { 4542 for (PackageSetting ps : mSettings.mPackages.values()) { 4543 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 4544 } 4545 } else { 4546 for (PackageParser.Package pkg : mPackages.values()) { 4547 PackageSetting ps = (PackageSetting)pkg.mExtras; 4548 if (ps != null) { 4549 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 4550 userId); 4551 } 4552 } 4553 } 4554 4555 return new ParceledListSlice<PackageInfo>(list); 4556 } 4557 } 4558 4559 @Override 4560 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 4561 if (!sUserManager.exists(userId)) return null; 4562 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4563 4564 // writer 4565 synchronized (mPackages) { 4566 ArrayList<ApplicationInfo> list; 4567 if (listUninstalled) { 4568 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 4569 for (PackageSetting ps : mSettings.mPackages.values()) { 4570 ApplicationInfo ai; 4571 if (ps.pkg != null) { 4572 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 4573 ps.readUserState(userId), userId); 4574 } else { 4575 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 4576 } 4577 if (ai != null) { 4578 list.add(ai); 4579 } 4580 } 4581 } else { 4582 list = new ArrayList<ApplicationInfo>(mPackages.size()); 4583 for (PackageParser.Package p : mPackages.values()) { 4584 if (p.mExtras != null) { 4585 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4586 ((PackageSetting)p.mExtras).readUserState(userId), userId); 4587 if (ai != null) { 4588 list.add(ai); 4589 } 4590 } 4591 } 4592 } 4593 4594 return new ParceledListSlice<ApplicationInfo>(list); 4595 } 4596 } 4597 4598 public List<ApplicationInfo> getPersistentApplications(int flags) { 4599 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 4600 4601 // reader 4602 synchronized (mPackages) { 4603 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 4604 final int userId = UserHandle.getCallingUserId(); 4605 while (i.hasNext()) { 4606 final PackageParser.Package p = i.next(); 4607 if (p.applicationInfo != null 4608 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 4609 && (!mSafeMode || isSystemApp(p))) { 4610 PackageSetting ps = mSettings.mPackages.get(p.packageName); 4611 if (ps != null) { 4612 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4613 ps.readUserState(userId), userId); 4614 if (ai != null) { 4615 finalList.add(ai); 4616 } 4617 } 4618 } 4619 } 4620 } 4621 4622 return finalList; 4623 } 4624 4625 @Override 4626 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 4627 if (!sUserManager.exists(userId)) return null; 4628 // reader 4629 synchronized (mPackages) { 4630 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 4631 PackageSetting ps = provider != null 4632 ? mSettings.mPackages.get(provider.owner.packageName) 4633 : null; 4634 return ps != null 4635 && mSettings.isEnabledLPr(provider.info, flags, userId) 4636 && (!mSafeMode || (provider.info.applicationInfo.flags 4637 &ApplicationInfo.FLAG_SYSTEM) != 0) 4638 ? PackageParser.generateProviderInfo(provider, flags, 4639 ps.readUserState(userId), userId) 4640 : null; 4641 } 4642 } 4643 4644 /** 4645 * @deprecated 4646 */ 4647 @Deprecated 4648 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 4649 // reader 4650 synchronized (mPackages) { 4651 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 4652 .entrySet().iterator(); 4653 final int userId = UserHandle.getCallingUserId(); 4654 while (i.hasNext()) { 4655 Map.Entry<String, PackageParser.Provider> entry = i.next(); 4656 PackageParser.Provider p = entry.getValue(); 4657 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4658 4659 if (ps != null && p.syncable 4660 && (!mSafeMode || (p.info.applicationInfo.flags 4661 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 4662 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 4663 ps.readUserState(userId), userId); 4664 if (info != null) { 4665 outNames.add(entry.getKey()); 4666 outInfo.add(info); 4667 } 4668 } 4669 } 4670 } 4671 } 4672 4673 @Override 4674 public List<ProviderInfo> queryContentProviders(String processName, 4675 int uid, int flags) { 4676 ArrayList<ProviderInfo> finalList = null; 4677 // reader 4678 synchronized (mPackages) { 4679 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 4680 final int userId = processName != null ? 4681 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 4682 while (i.hasNext()) { 4683 final PackageParser.Provider p = i.next(); 4684 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4685 if (ps != null && p.info.authority != null 4686 && (processName == null 4687 || (p.info.processName.equals(processName) 4688 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 4689 && mSettings.isEnabledLPr(p.info, flags, userId) 4690 && (!mSafeMode 4691 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 4692 if (finalList == null) { 4693 finalList = new ArrayList<ProviderInfo>(3); 4694 } 4695 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 4696 ps.readUserState(userId), userId); 4697 if (info != null) { 4698 finalList.add(info); 4699 } 4700 } 4701 } 4702 } 4703 4704 if (finalList != null) { 4705 Collections.sort(finalList, mProviderInitOrderSorter); 4706 } 4707 4708 return finalList; 4709 } 4710 4711 @Override 4712 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 4713 int flags) { 4714 // reader 4715 synchronized (mPackages) { 4716 final PackageParser.Instrumentation i = mInstrumentation.get(name); 4717 return PackageParser.generateInstrumentationInfo(i, flags); 4718 } 4719 } 4720 4721 @Override 4722 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 4723 int flags) { 4724 ArrayList<InstrumentationInfo> finalList = 4725 new ArrayList<InstrumentationInfo>(); 4726 4727 // reader 4728 synchronized (mPackages) { 4729 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 4730 while (i.hasNext()) { 4731 final PackageParser.Instrumentation p = i.next(); 4732 if (targetPackage == null 4733 || targetPackage.equals(p.info.targetPackage)) { 4734 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 4735 flags); 4736 if (ii != null) { 4737 finalList.add(ii); 4738 } 4739 } 4740 } 4741 } 4742 4743 return finalList; 4744 } 4745 4746 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 4747 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 4748 if (overlays == null) { 4749 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 4750 return; 4751 } 4752 for (PackageParser.Package opkg : overlays.values()) { 4753 // Not much to do if idmap fails: we already logged the error 4754 // and we certainly don't want to abort installation of pkg simply 4755 // because an overlay didn't fit properly. For these reasons, 4756 // ignore the return value of createIdmapForPackagePairLI. 4757 createIdmapForPackagePairLI(pkg, opkg); 4758 } 4759 } 4760 4761 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 4762 PackageParser.Package opkg) { 4763 if (!opkg.mTrustedOverlay) { 4764 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 4765 opkg.baseCodePath + ": overlay not trusted"); 4766 return false; 4767 } 4768 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 4769 if (overlaySet == null) { 4770 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 4771 opkg.baseCodePath + " but target package has no known overlays"); 4772 return false; 4773 } 4774 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4775 // TODO: generate idmap for split APKs 4776 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 4777 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 4778 + opkg.baseCodePath); 4779 return false; 4780 } 4781 PackageParser.Package[] overlayArray = 4782 overlaySet.values().toArray(new PackageParser.Package[0]); 4783 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 4784 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 4785 return p1.mOverlayPriority - p2.mOverlayPriority; 4786 } 4787 }; 4788 Arrays.sort(overlayArray, cmp); 4789 4790 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 4791 int i = 0; 4792 for (PackageParser.Package p : overlayArray) { 4793 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 4794 } 4795 return true; 4796 } 4797 4798 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 4799 final File[] files = dir.listFiles(); 4800 if (ArrayUtils.isEmpty(files)) { 4801 Log.d(TAG, "No files in app dir " + dir); 4802 return; 4803 } 4804 4805 if (DEBUG_PACKAGE_SCANNING) { 4806 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 4807 + " flags=0x" + Integer.toHexString(parseFlags)); 4808 } 4809 4810 for (File file : files) { 4811 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 4812 && !PackageInstallerService.isStageName(file.getName()); 4813 if (!isPackage) { 4814 // Ignore entries which are not packages 4815 continue; 4816 } 4817 try { 4818 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 4819 scanFlags, currentTime, null); 4820 } catch (PackageManagerException e) { 4821 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 4822 4823 // Delete invalid userdata apps 4824 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 4825 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 4826 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 4827 if (file.isDirectory()) { 4828 mInstaller.rmPackageDir(file.getAbsolutePath()); 4829 } else { 4830 file.delete(); 4831 } 4832 } 4833 } 4834 } 4835 } 4836 4837 private static File getSettingsProblemFile() { 4838 File dataDir = Environment.getDataDirectory(); 4839 File systemDir = new File(dataDir, "system"); 4840 File fname = new File(systemDir, "uiderrors.txt"); 4841 return fname; 4842 } 4843 4844 static void reportSettingsProblem(int priority, String msg) { 4845 logCriticalInfo(priority, msg); 4846 } 4847 4848 static void logCriticalInfo(int priority, String msg) { 4849 Slog.println(priority, TAG, msg); 4850 EventLogTags.writePmCriticalInfo(msg); 4851 try { 4852 File fname = getSettingsProblemFile(); 4853 FileOutputStream out = new FileOutputStream(fname, true); 4854 PrintWriter pw = new FastPrintWriter(out); 4855 SimpleDateFormat formatter = new SimpleDateFormat(); 4856 String dateString = formatter.format(new Date(System.currentTimeMillis())); 4857 pw.println(dateString + ": " + msg); 4858 pw.close(); 4859 FileUtils.setPermissions( 4860 fname.toString(), 4861 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 4862 -1, -1); 4863 } catch (java.io.IOException e) { 4864 } 4865 } 4866 4867 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 4868 PackageParser.Package pkg, File srcFile, int parseFlags) 4869 throws PackageManagerException { 4870 if (ps != null 4871 && ps.codePath.equals(srcFile) 4872 && ps.timeStamp == srcFile.lastModified() 4873 && !isCompatSignatureUpdateNeeded(pkg) 4874 && !isRecoverSignatureUpdateNeeded(pkg)) { 4875 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 4876 if (ps.signatures.mSignatures != null 4877 && ps.signatures.mSignatures.length != 0 4878 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) { 4879 // Optimization: reuse the existing cached certificates 4880 // if the package appears to be unchanged. 4881 pkg.mSignatures = ps.signatures.mSignatures; 4882 KeySetManagerService ksms = mSettings.mKeySetManagerService; 4883 synchronized (mPackages) { 4884 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 4885 } 4886 return; 4887 } 4888 4889 Slog.w(TAG, "PackageSetting for " + ps.name 4890 + " is missing signatures. Collecting certs again to recover them."); 4891 } else { 4892 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 4893 } 4894 4895 try { 4896 pp.collectCertificates(pkg, parseFlags); 4897 pp.collectManifestDigest(pkg); 4898 } catch (PackageParserException e) { 4899 throw PackageManagerException.from(e); 4900 } 4901 } 4902 4903 /* 4904 * Scan a package and return the newly parsed package. 4905 * Returns null in case of errors and the error code is stored in mLastScanError 4906 */ 4907 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 4908 long currentTime, UserHandle user) throws PackageManagerException { 4909 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 4910 parseFlags |= mDefParseFlags; 4911 PackageParser pp = new PackageParser(); 4912 pp.setSeparateProcesses(mSeparateProcesses); 4913 pp.setOnlyCoreApps(mOnlyCore); 4914 pp.setDisplayMetrics(mMetrics); 4915 4916 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 4917 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 4918 } 4919 4920 final PackageParser.Package pkg; 4921 try { 4922 pkg = pp.parsePackage(scanFile, parseFlags); 4923 } catch (PackageParserException e) { 4924 throw PackageManagerException.from(e); 4925 } 4926 4927 PackageSetting ps = null; 4928 PackageSetting updatedPkg; 4929 // reader 4930 synchronized (mPackages) { 4931 // Look to see if we already know about this package. 4932 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 4933 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 4934 // This package has been renamed to its original name. Let's 4935 // use that. 4936 ps = mSettings.peekPackageLPr(oldName); 4937 } 4938 // If there was no original package, see one for the real package name. 4939 if (ps == null) { 4940 ps = mSettings.peekPackageLPr(pkg.packageName); 4941 } 4942 // Check to see if this package could be hiding/updating a system 4943 // package. Must look for it either under the original or real 4944 // package name depending on our state. 4945 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 4946 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 4947 } 4948 boolean updatedPkgBetter = false; 4949 // First check if this is a system package that may involve an update 4950 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 4951 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 4952 // it needs to drop FLAG_PRIVILEGED. 4953 if (locationIsPrivileged(scanFile)) { 4954 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 4955 } else { 4956 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 4957 } 4958 4959 if (ps != null && !ps.codePath.equals(scanFile)) { 4960 // The path has changed from what was last scanned... check the 4961 // version of the new path against what we have stored to determine 4962 // what to do. 4963 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 4964 if (pkg.mVersionCode <= ps.versionCode) { 4965 // The system package has been updated and the code path does not match 4966 // Ignore entry. Skip it. 4967 Slog.i(TAG, "Package " + ps.name + " at " + scanFile 4968 + " ignored: updated version " + ps.versionCode 4969 + " better than this " + pkg.mVersionCode); 4970 if (!updatedPkg.codePath.equals(scanFile)) { 4971 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 4972 + ps.name + " changing from " + updatedPkg.codePathString 4973 + " to " + scanFile); 4974 updatedPkg.codePath = scanFile; 4975 updatedPkg.codePathString = scanFile.toString(); 4976 updatedPkg.resourcePath = scanFile; 4977 updatedPkg.resourcePathString = scanFile.toString(); 4978 } 4979 updatedPkg.pkg = pkg; 4980 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null); 4981 } else { 4982 // The current app on the system partition is better than 4983 // what we have updated to on the data partition; switch 4984 // back to the system partition version. 4985 // At this point, its safely assumed that package installation for 4986 // apps in system partition will go through. If not there won't be a working 4987 // version of the app 4988 // writer 4989 synchronized (mPackages) { 4990 // Just remove the loaded entries from package lists. 4991 mPackages.remove(ps.name); 4992 } 4993 4994 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 4995 + " reverting from " + ps.codePathString 4996 + ": new version " + pkg.mVersionCode 4997 + " better than installed " + ps.versionCode); 4998 4999 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5000 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 5001 getAppDexInstructionSets(ps)); 5002 synchronized (mInstallLock) { 5003 args.cleanUpResourcesLI(); 5004 } 5005 synchronized (mPackages) { 5006 mSettings.enableSystemPackageLPw(ps.name); 5007 } 5008 updatedPkgBetter = true; 5009 } 5010 } 5011 } 5012 5013 if (updatedPkg != null) { 5014 // An updated system app will not have the PARSE_IS_SYSTEM flag set 5015 // initially 5016 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 5017 5018 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 5019 // flag set initially 5020 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 5021 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 5022 } 5023 } 5024 5025 // Verify certificates against what was last scanned 5026 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 5027 5028 /* 5029 * A new system app appeared, but we already had a non-system one of the 5030 * same name installed earlier. 5031 */ 5032 boolean shouldHideSystemApp = false; 5033 if (updatedPkg == null && ps != null 5034 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 5035 /* 5036 * Check to make sure the signatures match first. If they don't, 5037 * wipe the installed application and its data. 5038 */ 5039 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 5040 != PackageManager.SIGNATURE_MATCH) { 5041 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 5042 + " signatures don't match existing userdata copy; removing"); 5043 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 5044 ps = null; 5045 } else { 5046 /* 5047 * If the newly-added system app is an older version than the 5048 * already installed version, hide it. It will be scanned later 5049 * and re-added like an update. 5050 */ 5051 if (pkg.mVersionCode <= ps.versionCode) { 5052 shouldHideSystemApp = true; 5053 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 5054 + " but new version " + pkg.mVersionCode + " better than installed " 5055 + ps.versionCode + "; hiding system"); 5056 } else { 5057 /* 5058 * The newly found system app is a newer version that the 5059 * one previously installed. Simply remove the 5060 * already-installed application and replace it with our own 5061 * while keeping the application data. 5062 */ 5063 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5064 + " reverting from " + ps.codePathString + ": new version " 5065 + pkg.mVersionCode + " better than installed " + ps.versionCode); 5066 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5067 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 5068 getAppDexInstructionSets(ps)); 5069 synchronized (mInstallLock) { 5070 args.cleanUpResourcesLI(); 5071 } 5072 } 5073 } 5074 } 5075 5076 // The apk is forward locked (not public) if its code and resources 5077 // are kept in different files. (except for app in either system or 5078 // vendor path). 5079 // TODO grab this value from PackageSettings 5080 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5081 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 5082 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 5083 } 5084 } 5085 5086 // TODO: extend to support forward-locked splits 5087 String resourcePath = null; 5088 String baseResourcePath = null; 5089 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 5090 if (ps != null && ps.resourcePathString != null) { 5091 resourcePath = ps.resourcePathString; 5092 baseResourcePath = ps.resourcePathString; 5093 } else { 5094 // Should not happen at all. Just log an error. 5095 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 5096 } 5097 } else { 5098 resourcePath = pkg.codePath; 5099 baseResourcePath = pkg.baseCodePath; 5100 } 5101 5102 // Set application objects path explicitly. 5103 pkg.applicationInfo.setCodePath(pkg.codePath); 5104 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 5105 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 5106 pkg.applicationInfo.setResourcePath(resourcePath); 5107 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 5108 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 5109 5110 // Note that we invoke the following method only if we are about to unpack an application 5111 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 5112 | SCAN_UPDATE_SIGNATURE, currentTime, user); 5113 5114 /* 5115 * If the system app should be overridden by a previously installed 5116 * data, hide the system app now and let the /data/app scan pick it up 5117 * again. 5118 */ 5119 if (shouldHideSystemApp) { 5120 synchronized (mPackages) { 5121 /* 5122 * We have to grant systems permissions before we hide, because 5123 * grantPermissions will assume the package update is trying to 5124 * expand its permissions. 5125 */ 5126 grantPermissionsLPw(pkg, true, pkg.packageName); 5127 mSettings.disableSystemPackageLPw(pkg.packageName); 5128 } 5129 } 5130 5131 return scannedPkg; 5132 } 5133 5134 private static String fixProcessName(String defProcessName, 5135 String processName, int uid) { 5136 if (processName == null) { 5137 return defProcessName; 5138 } 5139 return processName; 5140 } 5141 5142 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 5143 throws PackageManagerException { 5144 if (pkgSetting.signatures.mSignatures != null) { 5145 // Already existing package. Make sure signatures match 5146 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 5147 == PackageManager.SIGNATURE_MATCH; 5148 if (!match) { 5149 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 5150 == PackageManager.SIGNATURE_MATCH; 5151 } 5152 if (!match) { 5153 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 5154 == PackageManager.SIGNATURE_MATCH; 5155 } 5156 if (!match) { 5157 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5158 + pkg.packageName + " signatures do not match the " 5159 + "previously installed version; ignoring!"); 5160 } 5161 } 5162 5163 // Check for shared user signatures 5164 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 5165 // Already existing package. Make sure signatures match 5166 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5167 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 5168 if (!match) { 5169 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 5170 == PackageManager.SIGNATURE_MATCH; 5171 } 5172 if (!match) { 5173 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 5174 == PackageManager.SIGNATURE_MATCH; 5175 } 5176 if (!match) { 5177 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 5178 "Package " + pkg.packageName 5179 + " has no signatures that match those in shared user " 5180 + pkgSetting.sharedUser.name + "; ignoring!"); 5181 } 5182 } 5183 } 5184 5185 /** 5186 * Enforces that only the system UID or root's UID can call a method exposed 5187 * via Binder. 5188 * 5189 * @param message used as message if SecurityException is thrown 5190 * @throws SecurityException if the caller is not system or root 5191 */ 5192 private static final void enforceSystemOrRoot(String message) { 5193 final int uid = Binder.getCallingUid(); 5194 if (uid != Process.SYSTEM_UID && uid != 0) { 5195 throw new SecurityException(message); 5196 } 5197 } 5198 5199 @Override 5200 public void performBootDexOpt() { 5201 enforceSystemOrRoot("Only the system can request dexopt be performed"); 5202 5203 // Before everything else, see whether we need to fstrim. 5204 try { 5205 IMountService ms = PackageHelper.getMountService(); 5206 if (ms != null) { 5207 final boolean isUpgrade = isUpgrade(); 5208 boolean doTrim = isUpgrade; 5209 if (doTrim) { 5210 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 5211 } else { 5212 final long interval = android.provider.Settings.Global.getLong( 5213 mContext.getContentResolver(), 5214 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 5215 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 5216 if (interval > 0) { 5217 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 5218 if (timeSinceLast > interval) { 5219 doTrim = true; 5220 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 5221 + "; running immediately"); 5222 } 5223 } 5224 } 5225 if (doTrim) { 5226 if (!isFirstBoot()) { 5227 try { 5228 ActivityManagerNative.getDefault().showBootMessage( 5229 mContext.getResources().getString( 5230 R.string.android_upgrading_fstrim), true); 5231 } catch (RemoteException e) { 5232 } 5233 } 5234 ms.runMaintenance(); 5235 } 5236 } else { 5237 Slog.e(TAG, "Mount service unavailable!"); 5238 } 5239 } catch (RemoteException e) { 5240 // Can't happen; MountService is local 5241 } 5242 5243 final ArraySet<PackageParser.Package> pkgs; 5244 synchronized (mPackages) { 5245 pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages(); 5246 } 5247 5248 if (pkgs != null) { 5249 // Sort apps by importance for dexopt ordering. Important apps are given more priority 5250 // in case the device runs out of space. 5251 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 5252 // Give priority to core apps. 5253 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5254 PackageParser.Package pkg = it.next(); 5255 if (pkg.coreApp) { 5256 if (DEBUG_DEXOPT) { 5257 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 5258 } 5259 sortedPkgs.add(pkg); 5260 it.remove(); 5261 } 5262 } 5263 // Give priority to system apps that listen for pre boot complete. 5264 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 5265 ArraySet<String> pkgNames = getPackageNamesForIntent(intent); 5266 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5267 PackageParser.Package pkg = it.next(); 5268 if (pkgNames.contains(pkg.packageName)) { 5269 if (DEBUG_DEXOPT) { 5270 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 5271 } 5272 sortedPkgs.add(pkg); 5273 it.remove(); 5274 } 5275 } 5276 // Give priority to system apps. 5277 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5278 PackageParser.Package pkg = it.next(); 5279 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 5280 if (DEBUG_DEXOPT) { 5281 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName); 5282 } 5283 sortedPkgs.add(pkg); 5284 it.remove(); 5285 } 5286 } 5287 // Give priority to updated system apps. 5288 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5289 PackageParser.Package pkg = it.next(); 5290 if (pkg.isUpdatedSystemApp()) { 5291 if (DEBUG_DEXOPT) { 5292 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName); 5293 } 5294 sortedPkgs.add(pkg); 5295 it.remove(); 5296 } 5297 } 5298 // Give priority to apps that listen for boot complete. 5299 intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 5300 pkgNames = getPackageNamesForIntent(intent); 5301 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5302 PackageParser.Package pkg = it.next(); 5303 if (pkgNames.contains(pkg.packageName)) { 5304 if (DEBUG_DEXOPT) { 5305 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName); 5306 } 5307 sortedPkgs.add(pkg); 5308 it.remove(); 5309 } 5310 } 5311 // Filter out packages that aren't recently used. 5312 filterRecentlyUsedApps(pkgs); 5313 // Add all remaining apps. 5314 for (PackageParser.Package pkg : pkgs) { 5315 if (DEBUG_DEXOPT) { 5316 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 5317 } 5318 sortedPkgs.add(pkg); 5319 } 5320 5321 // If we want to be lazy, filter everything that wasn't recently used. 5322 if (mLazyDexOpt) { 5323 filterRecentlyUsedApps(sortedPkgs); 5324 } 5325 5326 int i = 0; 5327 int total = sortedPkgs.size(); 5328 File dataDir = Environment.getDataDirectory(); 5329 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 5330 if (lowThreshold == 0) { 5331 throw new IllegalStateException("Invalid low memory threshold"); 5332 } 5333 for (PackageParser.Package pkg : sortedPkgs) { 5334 long usableSpace = dataDir.getUsableSpace(); 5335 if (usableSpace < lowThreshold) { 5336 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 5337 break; 5338 } 5339 performBootDexOpt(pkg, ++i, total); 5340 } 5341 } 5342 } 5343 5344 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 5345 // Filter out packages that aren't recently used. 5346 // 5347 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 5348 // should do a full dexopt. 5349 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 5350 int total = pkgs.size(); 5351 int skipped = 0; 5352 long now = System.currentTimeMillis(); 5353 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 5354 PackageParser.Package pkg = i.next(); 5355 long then = pkg.mLastPackageUsageTimeInMills; 5356 if (then + mDexOptLRUThresholdInMills < now) { 5357 if (DEBUG_DEXOPT) { 5358 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 5359 ((then == 0) ? "never" : new Date(then))); 5360 } 5361 i.remove(); 5362 skipped++; 5363 } 5364 } 5365 if (DEBUG_DEXOPT) { 5366 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 5367 } 5368 } 5369 } 5370 5371 private ArraySet<String> getPackageNamesForIntent(Intent intent) { 5372 List<ResolveInfo> ris = null; 5373 try { 5374 ris = AppGlobals.getPackageManager().queryIntentReceivers( 5375 intent, null, 0, UserHandle.USER_OWNER); 5376 } catch (RemoteException e) { 5377 } 5378 ArraySet<String> pkgNames = new ArraySet<String>(); 5379 if (ris != null) { 5380 for (ResolveInfo ri : ris) { 5381 pkgNames.add(ri.activityInfo.packageName); 5382 } 5383 } 5384 return pkgNames; 5385 } 5386 5387 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 5388 if (DEBUG_DEXOPT) { 5389 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 5390 } 5391 if (!isFirstBoot()) { 5392 try { 5393 ActivityManagerNative.getDefault().showBootMessage( 5394 mContext.getResources().getString(R.string.android_upgrading_apk, 5395 curr, total), true); 5396 } catch (RemoteException e) { 5397 } 5398 } 5399 PackageParser.Package p = pkg; 5400 synchronized (mInstallLock) { 5401 mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, 5402 false /* force dex */, false /* defer */, true /* include dependencies */); 5403 } 5404 } 5405 5406 @Override 5407 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 5408 return performDexOpt(packageName, instructionSet, false); 5409 } 5410 5411 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) { 5412 boolean dexopt = mLazyDexOpt || backgroundDexopt; 5413 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 5414 if (!dexopt && !updateUsage) { 5415 // We aren't going to dexopt or update usage, so bail early. 5416 return false; 5417 } 5418 PackageParser.Package p; 5419 final String targetInstructionSet; 5420 synchronized (mPackages) { 5421 p = mPackages.get(packageName); 5422 if (p == null) { 5423 return false; 5424 } 5425 if (updateUsage) { 5426 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 5427 } 5428 mPackageUsage.write(false); 5429 if (!dexopt) { 5430 // We aren't going to dexopt, so bail early. 5431 return false; 5432 } 5433 5434 targetInstructionSet = instructionSet != null ? instructionSet : 5435 getPrimaryInstructionSet(p.applicationInfo); 5436 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 5437 return false; 5438 } 5439 } 5440 5441 synchronized (mInstallLock) { 5442 final String[] instructionSets = new String[] { targetInstructionSet }; 5443 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, 5444 false /* forceDex */, false /* defer */, true /* inclDependencies */); 5445 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 5446 } 5447 } 5448 5449 public ArraySet<String> getPackagesThatNeedDexOpt() { 5450 ArraySet<String> pkgs = null; 5451 synchronized (mPackages) { 5452 for (PackageParser.Package p : mPackages.values()) { 5453 if (DEBUG_DEXOPT) { 5454 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 5455 } 5456 if (!p.mDexOptPerformed.isEmpty()) { 5457 continue; 5458 } 5459 if (pkgs == null) { 5460 pkgs = new ArraySet<String>(); 5461 } 5462 pkgs.add(p.packageName); 5463 } 5464 } 5465 return pkgs; 5466 } 5467 5468 public void shutdown() { 5469 mPackageUsage.write(true); 5470 } 5471 5472 @Override 5473 public void forceDexOpt(String packageName) { 5474 enforceSystemOrRoot("forceDexOpt"); 5475 5476 PackageParser.Package pkg; 5477 synchronized (mPackages) { 5478 pkg = mPackages.get(packageName); 5479 if (pkg == null) { 5480 throw new IllegalArgumentException("Missing package: " + packageName); 5481 } 5482 } 5483 5484 synchronized (mInstallLock) { 5485 final String[] instructionSets = new String[] { 5486 getPrimaryInstructionSet(pkg.applicationInfo) }; 5487 final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, 5488 true /*forceDex*/, false /* defer */, true /* inclDependencies */); 5489 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 5490 throw new IllegalStateException("Failed to dexopt: " + res); 5491 } 5492 } 5493 } 5494 5495 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 5496 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 5497 Slog.w(TAG, "Unable to update from " + oldPkg.name 5498 + " to " + newPkg.packageName 5499 + ": old package not in system partition"); 5500 return false; 5501 } else if (mPackages.get(oldPkg.name) != null) { 5502 Slog.w(TAG, "Unable to update from " + oldPkg.name 5503 + " to " + newPkg.packageName 5504 + ": old package still exists"); 5505 return false; 5506 } 5507 return true; 5508 } 5509 5510 private File getDataPathForPackage(String packageName, int userId) { 5511 /* 5512 * Until we fully support multiple users, return the directory we 5513 * previously would have. The PackageManagerTests will need to be 5514 * revised when this is changed back.. 5515 */ 5516 if (userId == 0) { 5517 return new File(mAppDataDir, packageName); 5518 } else { 5519 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId 5520 + File.separator + packageName); 5521 } 5522 } 5523 5524 private int createDataDirsLI(String packageName, int uid, String seinfo) { 5525 int[] users = sUserManager.getUserIds(); 5526 int res = mInstaller.install(packageName, uid, uid, seinfo); 5527 if (res < 0) { 5528 return res; 5529 } 5530 for (int user : users) { 5531 if (user != 0) { 5532 res = mInstaller.createUserData(packageName, 5533 UserHandle.getUid(user, uid), user, seinfo); 5534 if (res < 0) { 5535 return res; 5536 } 5537 } 5538 } 5539 return res; 5540 } 5541 5542 private int removeDataDirsLI(String packageName) { 5543 int[] users = sUserManager.getUserIds(); 5544 int res = 0; 5545 for (int user : users) { 5546 int resInner = mInstaller.remove(packageName, user); 5547 if (resInner < 0) { 5548 res = resInner; 5549 } 5550 } 5551 5552 return res; 5553 } 5554 5555 private int deleteCodeCacheDirsLI(String packageName) { 5556 int[] users = sUserManager.getUserIds(); 5557 int res = 0; 5558 for (int user : users) { 5559 int resInner = mInstaller.deleteCodeCacheFiles(packageName, user); 5560 if (resInner < 0) { 5561 res = resInner; 5562 } 5563 } 5564 return res; 5565 } 5566 5567 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 5568 PackageParser.Package changingLib) { 5569 if (file.path != null) { 5570 usesLibraryFiles.add(file.path); 5571 return; 5572 } 5573 PackageParser.Package p = mPackages.get(file.apk); 5574 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 5575 // If we are doing this while in the middle of updating a library apk, 5576 // then we need to make sure to use that new apk for determining the 5577 // dependencies here. (We haven't yet finished committing the new apk 5578 // to the package manager state.) 5579 if (p == null || p.packageName.equals(changingLib.packageName)) { 5580 p = changingLib; 5581 } 5582 } 5583 if (p != null) { 5584 usesLibraryFiles.addAll(p.getAllCodePaths()); 5585 } 5586 } 5587 5588 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 5589 PackageParser.Package changingLib) throws PackageManagerException { 5590 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 5591 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 5592 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 5593 for (int i=0; i<N; i++) { 5594 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 5595 if (file == null) { 5596 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 5597 "Package " + pkg.packageName + " requires unavailable shared library " 5598 + pkg.usesLibraries.get(i) + "; failing!"); 5599 } 5600 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5601 } 5602 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 5603 for (int i=0; i<N; i++) { 5604 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 5605 if (file == null) { 5606 Slog.w(TAG, "Package " + pkg.packageName 5607 + " desires unavailable shared library " 5608 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 5609 } else { 5610 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5611 } 5612 } 5613 N = usesLibraryFiles.size(); 5614 if (N > 0) { 5615 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 5616 } else { 5617 pkg.usesLibraryFiles = null; 5618 } 5619 } 5620 } 5621 5622 private static boolean hasString(List<String> list, List<String> which) { 5623 if (list == null) { 5624 return false; 5625 } 5626 for (int i=list.size()-1; i>=0; i--) { 5627 for (int j=which.size()-1; j>=0; j--) { 5628 if (which.get(j).equals(list.get(i))) { 5629 return true; 5630 } 5631 } 5632 } 5633 return false; 5634 } 5635 5636 private void updateAllSharedLibrariesLPw() { 5637 for (PackageParser.Package pkg : mPackages.values()) { 5638 try { 5639 updateSharedLibrariesLPw(pkg, null); 5640 } catch (PackageManagerException e) { 5641 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5642 } 5643 } 5644 } 5645 5646 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 5647 PackageParser.Package changingPkg) { 5648 ArrayList<PackageParser.Package> res = null; 5649 for (PackageParser.Package pkg : mPackages.values()) { 5650 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 5651 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 5652 if (res == null) { 5653 res = new ArrayList<PackageParser.Package>(); 5654 } 5655 res.add(pkg); 5656 try { 5657 updateSharedLibrariesLPw(pkg, changingPkg); 5658 } catch (PackageManagerException e) { 5659 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5660 } 5661 } 5662 } 5663 return res; 5664 } 5665 5666 /** 5667 * Derive the value of the {@code cpuAbiOverride} based on the provided 5668 * value and an optional stored value from the package settings. 5669 */ 5670 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 5671 String cpuAbiOverride = null; 5672 5673 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 5674 cpuAbiOverride = null; 5675 } else if (abiOverride != null) { 5676 cpuAbiOverride = abiOverride; 5677 } else if (settings != null) { 5678 cpuAbiOverride = settings.cpuAbiOverrideString; 5679 } 5680 5681 return cpuAbiOverride; 5682 } 5683 5684 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 5685 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5686 boolean success = false; 5687 try { 5688 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 5689 currentTime, user); 5690 success = true; 5691 return res; 5692 } finally { 5693 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5694 removeDataDirsLI(pkg.packageName); 5695 } 5696 } 5697 } 5698 5699 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 5700 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5701 final File scanFile = new File(pkg.codePath); 5702 if (pkg.applicationInfo.getCodePath() == null || 5703 pkg.applicationInfo.getResourcePath() == null) { 5704 // Bail out. The resource and code paths haven't been set. 5705 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 5706 "Code and resource paths haven't been set correctly"); 5707 } 5708 5709 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5710 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 5711 } else { 5712 // Only allow system apps to be flagged as core apps. 5713 pkg.coreApp = false; 5714 } 5715 5716 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 5717 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5718 } 5719 5720 if (mCustomResolverComponentName != null && 5721 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 5722 setUpCustomResolverActivity(pkg); 5723 } 5724 5725 if (pkg.packageName.equals("android")) { 5726 synchronized (mPackages) { 5727 if (mAndroidApplication != null) { 5728 Slog.w(TAG, "*************************************************"); 5729 Slog.w(TAG, "Core android package being redefined. Skipping."); 5730 Slog.w(TAG, " file=" + scanFile); 5731 Slog.w(TAG, "*************************************************"); 5732 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5733 "Core android package being redefined. Skipping."); 5734 } 5735 5736 // Set up information for our fall-back user intent resolution activity. 5737 mPlatformPackage = pkg; 5738 pkg.mVersionCode = mSdkVersion; 5739 mAndroidApplication = pkg.applicationInfo; 5740 5741 if (!mResolverReplaced) { 5742 mResolveActivity.applicationInfo = mAndroidApplication; 5743 mResolveActivity.name = ResolverActivity.class.getName(); 5744 mResolveActivity.packageName = mAndroidApplication.packageName; 5745 mResolveActivity.processName = "system:ui"; 5746 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5747 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 5748 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 5749 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 5750 mResolveActivity.exported = true; 5751 mResolveActivity.enabled = true; 5752 mResolveInfo.activityInfo = mResolveActivity; 5753 mResolveInfo.priority = 0; 5754 mResolveInfo.preferredOrder = 0; 5755 mResolveInfo.match = 0; 5756 mResolveComponentName = new ComponentName( 5757 mAndroidApplication.packageName, mResolveActivity.name); 5758 } 5759 } 5760 } 5761 5762 if (DEBUG_PACKAGE_SCANNING) { 5763 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5764 Log.d(TAG, "Scanning package " + pkg.packageName); 5765 } 5766 5767 if (mPackages.containsKey(pkg.packageName) 5768 || mSharedLibraries.containsKey(pkg.packageName)) { 5769 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5770 "Application package " + pkg.packageName 5771 + " already installed. Skipping duplicate."); 5772 } 5773 5774 // If we're only installing presumed-existing packages, require that the 5775 // scanned APK is both already known and at the path previously established 5776 // for it. Previously unknown packages we pick up normally, but if we have an 5777 // a priori expectation about this package's install presence, enforce it. 5778 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 5779 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 5780 if (known != null) { 5781 if (DEBUG_PACKAGE_SCANNING) { 5782 Log.d(TAG, "Examining " + pkg.codePath 5783 + " and requiring known paths " + known.codePathString 5784 + " & " + known.resourcePathString); 5785 } 5786 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 5787 || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { 5788 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 5789 "Application package " + pkg.packageName 5790 + " found at " + pkg.applicationInfo.getCodePath() 5791 + " but expected at " + known.codePathString + "; ignoring."); 5792 } 5793 } 5794 } 5795 5796 // Initialize package source and resource directories 5797 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 5798 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 5799 5800 SharedUserSetting suid = null; 5801 PackageSetting pkgSetting = null; 5802 5803 if (!isSystemApp(pkg)) { 5804 // Only system apps can use these features. 5805 pkg.mOriginalPackages = null; 5806 pkg.mRealPackage = null; 5807 pkg.mAdoptPermissions = null; 5808 } 5809 5810 // writer 5811 synchronized (mPackages) { 5812 if (pkg.mSharedUserId != null) { 5813 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 5814 if (suid == null) { 5815 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5816 "Creating application package " + pkg.packageName 5817 + " for shared user failed"); 5818 } 5819 if (DEBUG_PACKAGE_SCANNING) { 5820 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5821 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 5822 + "): packages=" + suid.packages); 5823 } 5824 } 5825 5826 // Check if we are renaming from an original package name. 5827 PackageSetting origPackage = null; 5828 String realName = null; 5829 if (pkg.mOriginalPackages != null) { 5830 // This package may need to be renamed to a previously 5831 // installed name. Let's check on that... 5832 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 5833 if (pkg.mOriginalPackages.contains(renamed)) { 5834 // This package had originally been installed as the 5835 // original name, and we have already taken care of 5836 // transitioning to the new one. Just update the new 5837 // one to continue using the old name. 5838 realName = pkg.mRealPackage; 5839 if (!pkg.packageName.equals(renamed)) { 5840 // Callers into this function may have already taken 5841 // care of renaming the package; only do it here if 5842 // it is not already done. 5843 pkg.setPackageName(renamed); 5844 } 5845 5846 } else { 5847 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 5848 if ((origPackage = mSettings.peekPackageLPr( 5849 pkg.mOriginalPackages.get(i))) != null) { 5850 // We do have the package already installed under its 5851 // original name... should we use it? 5852 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 5853 // New package is not compatible with original. 5854 origPackage = null; 5855 continue; 5856 } else if (origPackage.sharedUser != null) { 5857 // Make sure uid is compatible between packages. 5858 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 5859 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 5860 + " to " + pkg.packageName + ": old uid " 5861 + origPackage.sharedUser.name 5862 + " differs from " + pkg.mSharedUserId); 5863 origPackage = null; 5864 continue; 5865 } 5866 } else { 5867 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 5868 + pkg.packageName + " to old name " + origPackage.name); 5869 } 5870 break; 5871 } 5872 } 5873 } 5874 } 5875 5876 if (mTransferedPackages.contains(pkg.packageName)) { 5877 Slog.w(TAG, "Package " + pkg.packageName 5878 + " was transferred to another, but its .apk remains"); 5879 } 5880 5881 // Just create the setting, don't add it yet. For already existing packages 5882 // the PkgSetting exists already and doesn't have to be created. 5883 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 5884 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 5885 pkg.applicationInfo.primaryCpuAbi, 5886 pkg.applicationInfo.secondaryCpuAbi, 5887 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 5888 user, false); 5889 if (pkgSetting == null) { 5890 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5891 "Creating application package " + pkg.packageName + " failed"); 5892 } 5893 5894 if (pkgSetting.origPackage != null) { 5895 // If we are first transitioning from an original package, 5896 // fix up the new package's name now. We need to do this after 5897 // looking up the package under its new name, so getPackageLP 5898 // can take care of fiddling things correctly. 5899 pkg.setPackageName(origPackage.name); 5900 5901 // File a report about this. 5902 String msg = "New package " + pkgSetting.realName 5903 + " renamed to replace old package " + pkgSetting.name; 5904 reportSettingsProblem(Log.WARN, msg); 5905 5906 // Make a note of it. 5907 mTransferedPackages.add(origPackage.name); 5908 5909 // No longer need to retain this. 5910 pkgSetting.origPackage = null; 5911 } 5912 5913 if (realName != null) { 5914 // Make a note of it. 5915 mTransferedPackages.add(pkg.packageName); 5916 } 5917 5918 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 5919 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 5920 } 5921 5922 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5923 // Check all shared libraries and map to their actual file path. 5924 // We only do this here for apps not on a system dir, because those 5925 // are the only ones that can fail an install due to this. We 5926 // will take care of the system apps by updating all of their 5927 // library paths after the scan is done. 5928 updateSharedLibrariesLPw(pkg, null); 5929 } 5930 5931 if (mFoundPolicyFile) { 5932 SELinuxMMAC.assignSeinfoValue(pkg); 5933 } 5934 5935 pkg.applicationInfo.uid = pkgSetting.appId; 5936 pkg.mExtras = pkgSetting; 5937 if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) { 5938 try { 5939 verifySignaturesLP(pkgSetting, pkg); 5940 // We just determined the app is signed correctly, so bring 5941 // over the latest parsed certs. 5942 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5943 } catch (PackageManagerException e) { 5944 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5945 throw e; 5946 } 5947 // The signature has changed, but this package is in the system 5948 // image... let's recover! 5949 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5950 // However... if this package is part of a shared user, but it 5951 // doesn't match the signature of the shared user, let's fail. 5952 // What this means is that you can't change the signatures 5953 // associated with an overall shared user, which doesn't seem all 5954 // that unreasonable. 5955 if (pkgSetting.sharedUser != null) { 5956 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5957 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 5958 throw new PackageManagerException( 5959 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 5960 "Signature mismatch for shared user : " 5961 + pkgSetting.sharedUser); 5962 } 5963 } 5964 // File a report about this. 5965 String msg = "System package " + pkg.packageName 5966 + " signature changed; retaining data."; 5967 reportSettingsProblem(Log.WARN, msg); 5968 } 5969 } else { 5970 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) { 5971 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5972 + pkg.packageName + " upgrade keys do not match the " 5973 + "previously installed version"); 5974 } else { 5975 // We just determined the app is signed correctly, so bring 5976 // over the latest parsed certs. 5977 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5978 } 5979 } 5980 // Verify that this new package doesn't have any content providers 5981 // that conflict with existing packages. Only do this if the 5982 // package isn't already installed, since we don't want to break 5983 // things that are installed. 5984 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 5985 final int N = pkg.providers.size(); 5986 int i; 5987 for (i=0; i<N; i++) { 5988 PackageParser.Provider p = pkg.providers.get(i); 5989 if (p.info.authority != null) { 5990 String names[] = p.info.authority.split(";"); 5991 for (int j = 0; j < names.length; j++) { 5992 if (mProvidersByAuthority.containsKey(names[j])) { 5993 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 5994 final String otherPackageName = 5995 ((other != null && other.getComponentName() != null) ? 5996 other.getComponentName().getPackageName() : "?"); 5997 throw new PackageManagerException( 5998 INSTALL_FAILED_CONFLICTING_PROVIDER, 5999 "Can't install because provider name " + names[j] 6000 + " (in package " + pkg.applicationInfo.packageName 6001 + ") is already used by " + otherPackageName); 6002 } 6003 } 6004 } 6005 } 6006 } 6007 6008 if (pkg.mAdoptPermissions != null) { 6009 // This package wants to adopt ownership of permissions from 6010 // another package. 6011 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 6012 final String origName = pkg.mAdoptPermissions.get(i); 6013 final PackageSetting orig = mSettings.peekPackageLPr(origName); 6014 if (orig != null) { 6015 if (verifyPackageUpdateLPr(orig, pkg)) { 6016 Slog.i(TAG, "Adopting permissions from " + origName + " to " 6017 + pkg.packageName); 6018 mSettings.transferPermissionsLPw(origName, pkg.packageName); 6019 } 6020 } 6021 } 6022 } 6023 } 6024 6025 final String pkgName = pkg.packageName; 6026 6027 final long scanFileTime = scanFile.lastModified(); 6028 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 6029 pkg.applicationInfo.processName = fixProcessName( 6030 pkg.applicationInfo.packageName, 6031 pkg.applicationInfo.processName, 6032 pkg.applicationInfo.uid); 6033 6034 File dataPath; 6035 if (mPlatformPackage == pkg) { 6036 // The system package is special. 6037 dataPath = new File(Environment.getDataDirectory(), "system"); 6038 6039 pkg.applicationInfo.dataDir = dataPath.getPath(); 6040 6041 } else { 6042 // This is a normal package, need to make its data directory. 6043 dataPath = getDataPathForPackage(pkg.packageName, 0); 6044 6045 boolean uidError = false; 6046 if (dataPath.exists()) { 6047 int currentUid = 0; 6048 try { 6049 StructStat stat = Os.stat(dataPath.getPath()); 6050 currentUid = stat.st_uid; 6051 } catch (ErrnoException e) { 6052 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 6053 } 6054 6055 // If we have mismatched owners for the data path, we have a problem. 6056 if (currentUid != pkg.applicationInfo.uid) { 6057 boolean recovered = false; 6058 if (currentUid == 0) { 6059 // The directory somehow became owned by root. Wow. 6060 // This is probably because the system was stopped while 6061 // installd was in the middle of messing with its libs 6062 // directory. Ask installd to fix that. 6063 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid, 6064 pkg.applicationInfo.uid); 6065 if (ret >= 0) { 6066 recovered = true; 6067 String msg = "Package " + pkg.packageName 6068 + " unexpectedly changed to uid 0; recovered to " + 6069 + pkg.applicationInfo.uid; 6070 reportSettingsProblem(Log.WARN, msg); 6071 } 6072 } 6073 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6074 || (scanFlags&SCAN_BOOTING) != 0)) { 6075 // If this is a system app, we can at least delete its 6076 // current data so the application will still work. 6077 int ret = removeDataDirsLI(pkgName); 6078 if (ret >= 0) { 6079 // TODO: Kill the processes first 6080 // Old data gone! 6081 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6082 ? "System package " : "Third party package "; 6083 String msg = prefix + pkg.packageName 6084 + " has changed from uid: " 6085 + currentUid + " to " 6086 + pkg.applicationInfo.uid + "; old data erased"; 6087 reportSettingsProblem(Log.WARN, msg); 6088 recovered = true; 6089 6090 // And now re-install the app. 6091 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 6092 pkg.applicationInfo.seinfo); 6093 if (ret == -1) { 6094 // Ack should not happen! 6095 msg = prefix + pkg.packageName 6096 + " could not have data directory re-created after delete."; 6097 reportSettingsProblem(Log.WARN, msg); 6098 throw new PackageManagerException( 6099 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 6100 } 6101 } 6102 if (!recovered) { 6103 mHasSystemUidErrors = true; 6104 } 6105 } else if (!recovered) { 6106 // If we allow this install to proceed, we will be broken. 6107 // Abort, abort! 6108 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 6109 "scanPackageLI"); 6110 } 6111 if (!recovered) { 6112 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 6113 + pkg.applicationInfo.uid + "/fs_" 6114 + currentUid; 6115 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 6116 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 6117 String msg = "Package " + pkg.packageName 6118 + " has mismatched uid: " 6119 + currentUid + " on disk, " 6120 + pkg.applicationInfo.uid + " in settings"; 6121 // writer 6122 synchronized (mPackages) { 6123 mSettings.mReadMessages.append(msg); 6124 mSettings.mReadMessages.append('\n'); 6125 uidError = true; 6126 if (!pkgSetting.uidError) { 6127 reportSettingsProblem(Log.ERROR, msg); 6128 } 6129 } 6130 } 6131 } 6132 pkg.applicationInfo.dataDir = dataPath.getPath(); 6133 if (mShouldRestoreconData) { 6134 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 6135 mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo, 6136 pkg.applicationInfo.uid); 6137 } 6138 } else { 6139 if (DEBUG_PACKAGE_SCANNING) { 6140 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6141 Log.v(TAG, "Want this data dir: " + dataPath); 6142 } 6143 //invoke installer to do the actual installation 6144 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 6145 pkg.applicationInfo.seinfo); 6146 if (ret < 0) { 6147 // Error from installer 6148 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6149 "Unable to create data dirs [errorCode=" + ret + "]"); 6150 } 6151 6152 if (dataPath.exists()) { 6153 pkg.applicationInfo.dataDir = dataPath.getPath(); 6154 } else { 6155 Slog.w(TAG, "Unable to create data directory: " + dataPath); 6156 pkg.applicationInfo.dataDir = null; 6157 } 6158 } 6159 6160 pkgSetting.uidError = uidError; 6161 } 6162 6163 final String path = scanFile.getPath(); 6164 final String codePath = pkg.applicationInfo.getCodePath(); 6165 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 6166 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 6167 setBundledAppAbisAndRoots(pkg, pkgSetting); 6168 6169 // If we haven't found any native libraries for the app, check if it has 6170 // renderscript code. We'll need to force the app to 32 bit if it has 6171 // renderscript bitcode. 6172 if (pkg.applicationInfo.primaryCpuAbi == null 6173 && pkg.applicationInfo.secondaryCpuAbi == null 6174 && Build.SUPPORTED_64_BIT_ABIS.length > 0) { 6175 NativeLibraryHelper.Handle handle = null; 6176 try { 6177 handle = NativeLibraryHelper.Handle.create(scanFile); 6178 if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 6179 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6180 } 6181 } catch (IOException ioe) { 6182 Slog.w(TAG, "Error scanning system app : " + ioe); 6183 } finally { 6184 IoUtils.closeQuietly(handle); 6185 } 6186 } 6187 6188 setNativeLibraryPaths(pkg); 6189 } else { 6190 // TODO: We can probably be smarter about this stuff. For installed apps, 6191 // we can calculate this information at install time once and for all. For 6192 // system apps, we can probably assume that this information doesn't change 6193 // after the first boot scan. As things stand, we do lots of unnecessary work. 6194 6195 // Give ourselves some initial paths; we'll come back for another 6196 // pass once we've determined ABI below. 6197 setNativeLibraryPaths(pkg); 6198 6199 final boolean isAsec = pkg.isForwardLocked() || isExternal(pkg); 6200 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 6201 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 6202 6203 NativeLibraryHelper.Handle handle = null; 6204 try { 6205 handle = NativeLibraryHelper.Handle.create(scanFile); 6206 // TODO(multiArch): This can be null for apps that didn't go through the 6207 // usual installation process. We can calculate it again, like we 6208 // do during install time. 6209 // 6210 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 6211 // unnecessary. 6212 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 6213 6214 // Null out the abis so that they can be recalculated. 6215 pkg.applicationInfo.primaryCpuAbi = null; 6216 pkg.applicationInfo.secondaryCpuAbi = null; 6217 if (isMultiArch(pkg.applicationInfo)) { 6218 // Warn if we've set an abiOverride for multi-lib packages.. 6219 // By definition, we need to copy both 32 and 64 bit libraries for 6220 // such packages. 6221 if (pkg.cpuAbiOverride != null 6222 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 6223 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 6224 } 6225 6226 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 6227 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 6228 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 6229 if (isAsec) { 6230 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 6231 } else { 6232 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6233 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 6234 useIsaSpecificSubdirs); 6235 } 6236 } 6237 6238 maybeThrowExceptionForMultiArchCopy( 6239 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 6240 6241 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 6242 if (isAsec) { 6243 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 6244 } else { 6245 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6246 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 6247 useIsaSpecificSubdirs); 6248 } 6249 } 6250 6251 maybeThrowExceptionForMultiArchCopy( 6252 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 6253 6254 if (abi64 >= 0) { 6255 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 6256 } 6257 6258 if (abi32 >= 0) { 6259 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 6260 if (abi64 >= 0) { 6261 pkg.applicationInfo.secondaryCpuAbi = abi; 6262 } else { 6263 pkg.applicationInfo.primaryCpuAbi = abi; 6264 } 6265 } 6266 } else { 6267 String[] abiList = (cpuAbiOverride != null) ? 6268 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 6269 6270 // Enable gross and lame hacks for apps that are built with old 6271 // SDK tools. We must scan their APKs for renderscript bitcode and 6272 // not launch them if it's present. Don't bother checking on devices 6273 // that don't have 64 bit support. 6274 boolean needsRenderScriptOverride = false; 6275 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 6276 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 6277 abiList = Build.SUPPORTED_32_BIT_ABIS; 6278 needsRenderScriptOverride = true; 6279 } 6280 6281 final int copyRet; 6282 if (isAsec) { 6283 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 6284 } else { 6285 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6286 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 6287 } 6288 6289 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 6290 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 6291 "Error unpackaging native libs for app, errorCode=" + copyRet); 6292 } 6293 6294 if (copyRet >= 0) { 6295 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 6296 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 6297 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 6298 } else if (needsRenderScriptOverride) { 6299 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 6300 } 6301 } 6302 } catch (IOException ioe) { 6303 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 6304 } finally { 6305 IoUtils.closeQuietly(handle); 6306 } 6307 6308 // Now that we've calculated the ABIs and determined if it's an internal app, 6309 // we will go ahead and populate the nativeLibraryPath. 6310 setNativeLibraryPaths(pkg); 6311 6312 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 6313 final int[] userIds = sUserManager.getUserIds(); 6314 synchronized (mInstallLock) { 6315 // Create a native library symlink only if we have native libraries 6316 // and if the native libraries are 32 bit libraries. We do not provide 6317 // this symlink for 64 bit libraries. 6318 if (pkg.applicationInfo.primaryCpuAbi != null && 6319 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 6320 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 6321 for (int userId : userIds) { 6322 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) { 6323 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 6324 "Failed linking native library dir (user=" + userId + ")"); 6325 } 6326 } 6327 } 6328 } 6329 } 6330 6331 // This is a special case for the "system" package, where the ABI is 6332 // dictated by the zygote configuration (and init.rc). We should keep track 6333 // of this ABI so that we can deal with "normal" applications that run under 6334 // the same UID correctly. 6335 if (mPlatformPackage == pkg) { 6336 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 6337 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 6338 } 6339 6340 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 6341 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 6342 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 6343 // Copy the derived override back to the parsed package, so that we can 6344 // update the package settings accordingly. 6345 pkg.cpuAbiOverride = cpuAbiOverride; 6346 6347 if (DEBUG_ABI_SELECTION) { 6348 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 6349 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 6350 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 6351 } 6352 6353 // Push the derived path down into PackageSettings so we know what to 6354 // clean up at uninstall time. 6355 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 6356 6357 if (DEBUG_ABI_SELECTION) { 6358 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 6359 " primary=" + pkg.applicationInfo.primaryCpuAbi + 6360 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 6361 } 6362 6363 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 6364 // We don't do this here during boot because we can do it all 6365 // at once after scanning all existing packages. 6366 // 6367 // We also do this *before* we perform dexopt on this package, so that 6368 // we can avoid redundant dexopts, and also to make sure we've got the 6369 // code and package path correct. 6370 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 6371 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); 6372 } 6373 6374 if ((scanFlags & SCAN_NO_DEX) == 0) { 6375 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, 6376 forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */); 6377 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6378 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 6379 } 6380 } 6381 if (mFactoryTest && pkg.requestedPermissions.contains( 6382 android.Manifest.permission.FACTORY_TEST)) { 6383 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 6384 } 6385 6386 ArrayList<PackageParser.Package> clientLibPkgs = null; 6387 6388 // writer 6389 synchronized (mPackages) { 6390 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6391 // Only system apps can add new shared libraries. 6392 if (pkg.libraryNames != null) { 6393 for (int i=0; i<pkg.libraryNames.size(); i++) { 6394 String name = pkg.libraryNames.get(i); 6395 boolean allowed = false; 6396 if (pkg.isUpdatedSystemApp()) { 6397 // New library entries can only be added through the 6398 // system image. This is important to get rid of a lot 6399 // of nasty edge cases: for example if we allowed a non- 6400 // system update of the app to add a library, then uninstalling 6401 // the update would make the library go away, and assumptions 6402 // we made such as through app install filtering would now 6403 // have allowed apps on the device which aren't compatible 6404 // with it. Better to just have the restriction here, be 6405 // conservative, and create many fewer cases that can negatively 6406 // impact the user experience. 6407 final PackageSetting sysPs = mSettings 6408 .getDisabledSystemPkgLPr(pkg.packageName); 6409 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 6410 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 6411 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 6412 allowed = true; 6413 allowed = true; 6414 break; 6415 } 6416 } 6417 } 6418 } else { 6419 allowed = true; 6420 } 6421 if (allowed) { 6422 if (!mSharedLibraries.containsKey(name)) { 6423 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 6424 } else if (!name.equals(pkg.packageName)) { 6425 Slog.w(TAG, "Package " + pkg.packageName + " library " 6426 + name + " already exists; skipping"); 6427 } 6428 } else { 6429 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 6430 + name + " that is not declared on system image; skipping"); 6431 } 6432 } 6433 if ((scanFlags&SCAN_BOOTING) == 0) { 6434 // If we are not booting, we need to update any applications 6435 // that are clients of our shared library. If we are booting, 6436 // this will all be done once the scan is complete. 6437 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 6438 } 6439 } 6440 } 6441 } 6442 6443 // We also need to dexopt any apps that are dependent on this library. Note that 6444 // if these fail, we should abort the install since installing the library will 6445 // result in some apps being broken. 6446 if (clientLibPkgs != null) { 6447 if ((scanFlags & SCAN_NO_DEX) == 0) { 6448 for (int i = 0; i < clientLibPkgs.size(); i++) { 6449 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6450 int result = mPackageDexOptimizer.performDexOpt(clientPkg, 6451 null /* instruction sets */, forceDex, 6452 (scanFlags & SCAN_DEFER_DEX) != 0, false); 6453 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6454 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 6455 "scanPackageLI failed to dexopt clientLibPkgs"); 6456 } 6457 } 6458 } 6459 } 6460 6461 // Request the ActivityManager to kill the process(only for existing packages) 6462 // so that we do not end up in a confused state while the user is still using the older 6463 // version of the application while the new one gets installed. 6464 if ((scanFlags & SCAN_REPLACING) != 0) { 6465 killApplication(pkg.applicationInfo.packageName, 6466 pkg.applicationInfo.uid, "update pkg"); 6467 } 6468 6469 // Also need to kill any apps that are dependent on the library. 6470 if (clientLibPkgs != null) { 6471 for (int i=0; i<clientLibPkgs.size(); i++) { 6472 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6473 killApplication(clientPkg.applicationInfo.packageName, 6474 clientPkg.applicationInfo.uid, "update lib"); 6475 } 6476 } 6477 6478 // writer 6479 synchronized (mPackages) { 6480 // We don't expect installation to fail beyond this point 6481 6482 // Add the new setting to mSettings 6483 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 6484 // Add the new setting to mPackages 6485 mPackages.put(pkg.applicationInfo.packageName, pkg); 6486 // Make sure we don't accidentally delete its data. 6487 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 6488 while (iter.hasNext()) { 6489 PackageCleanItem item = iter.next(); 6490 if (pkgName.equals(item.packageName)) { 6491 iter.remove(); 6492 } 6493 } 6494 6495 // Take care of first install / last update times. 6496 if (currentTime != 0) { 6497 if (pkgSetting.firstInstallTime == 0) { 6498 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 6499 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 6500 pkgSetting.lastUpdateTime = currentTime; 6501 } 6502 } else if (pkgSetting.firstInstallTime == 0) { 6503 // We need *something*. Take time time stamp of the file. 6504 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 6505 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 6506 if (scanFileTime != pkgSetting.timeStamp) { 6507 // A package on the system image has changed; consider this 6508 // to be an update. 6509 pkgSetting.lastUpdateTime = scanFileTime; 6510 } 6511 } 6512 6513 // Add the package's KeySets to the global KeySetManagerService 6514 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6515 try { 6516 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys); 6517 if (pkg.mKeySetMapping != null) { 6518 ksms.addDefinedKeySetsToPackageLPw(pkg.packageName, pkg.mKeySetMapping); 6519 if (pkg.mUpgradeKeySets != null) { 6520 ksms.addUpgradeKeySetsToPackageLPw(pkg.packageName, pkg.mUpgradeKeySets); 6521 } 6522 } 6523 } catch (NullPointerException e) { 6524 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 6525 } catch (IllegalArgumentException e) { 6526 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 6527 } 6528 6529 int N = pkg.providers.size(); 6530 StringBuilder r = null; 6531 int i; 6532 for (i=0; i<N; i++) { 6533 PackageParser.Provider p = pkg.providers.get(i); 6534 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 6535 p.info.processName, pkg.applicationInfo.uid); 6536 mProviders.addProvider(p); 6537 p.syncable = p.info.isSyncable; 6538 if (p.info.authority != null) { 6539 String names[] = p.info.authority.split(";"); 6540 p.info.authority = null; 6541 for (int j = 0; j < names.length; j++) { 6542 if (j == 1 && p.syncable) { 6543 // We only want the first authority for a provider to possibly be 6544 // syncable, so if we already added this provider using a different 6545 // authority clear the syncable flag. We copy the provider before 6546 // changing it because the mProviders object contains a reference 6547 // to a provider that we don't want to change. 6548 // Only do this for the second authority since the resulting provider 6549 // object can be the same for all future authorities for this provider. 6550 p = new PackageParser.Provider(p); 6551 p.syncable = false; 6552 } 6553 if (!mProvidersByAuthority.containsKey(names[j])) { 6554 mProvidersByAuthority.put(names[j], p); 6555 if (p.info.authority == null) { 6556 p.info.authority = names[j]; 6557 } else { 6558 p.info.authority = p.info.authority + ";" + names[j]; 6559 } 6560 if (DEBUG_PACKAGE_SCANNING) { 6561 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6562 Log.d(TAG, "Registered content provider: " + names[j] 6563 + ", className = " + p.info.name + ", isSyncable = " 6564 + p.info.isSyncable); 6565 } 6566 } else { 6567 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6568 Slog.w(TAG, "Skipping provider name " + names[j] + 6569 " (in package " + pkg.applicationInfo.packageName + 6570 "): name already used by " 6571 + ((other != null && other.getComponentName() != null) 6572 ? other.getComponentName().getPackageName() : "?")); 6573 } 6574 } 6575 } 6576 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6577 if (r == null) { 6578 r = new StringBuilder(256); 6579 } else { 6580 r.append(' '); 6581 } 6582 r.append(p.info.name); 6583 } 6584 } 6585 if (r != null) { 6586 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 6587 } 6588 6589 N = pkg.services.size(); 6590 r = null; 6591 for (i=0; i<N; i++) { 6592 PackageParser.Service s = pkg.services.get(i); 6593 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 6594 s.info.processName, pkg.applicationInfo.uid); 6595 mServices.addService(s); 6596 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6597 if (r == null) { 6598 r = new StringBuilder(256); 6599 } else { 6600 r.append(' '); 6601 } 6602 r.append(s.info.name); 6603 } 6604 } 6605 if (r != null) { 6606 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 6607 } 6608 6609 N = pkg.receivers.size(); 6610 r = null; 6611 for (i=0; i<N; i++) { 6612 PackageParser.Activity a = pkg.receivers.get(i); 6613 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6614 a.info.processName, pkg.applicationInfo.uid); 6615 mReceivers.addActivity(a, "receiver"); 6616 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6617 if (r == null) { 6618 r = new StringBuilder(256); 6619 } else { 6620 r.append(' '); 6621 } 6622 r.append(a.info.name); 6623 } 6624 } 6625 if (r != null) { 6626 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 6627 } 6628 6629 N = pkg.activities.size(); 6630 r = null; 6631 for (i=0; i<N; i++) { 6632 PackageParser.Activity a = pkg.activities.get(i); 6633 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6634 a.info.processName, pkg.applicationInfo.uid); 6635 mActivities.addActivity(a, "activity"); 6636 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6637 if (r == null) { 6638 r = new StringBuilder(256); 6639 } else { 6640 r.append(' '); 6641 } 6642 r.append(a.info.name); 6643 } 6644 } 6645 if (r != null) { 6646 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 6647 } 6648 6649 N = pkg.permissionGroups.size(); 6650 r = null; 6651 for (i=0; i<N; i++) { 6652 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 6653 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 6654 if (cur == null) { 6655 mPermissionGroups.put(pg.info.name, pg); 6656 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6657 if (r == null) { 6658 r = new StringBuilder(256); 6659 } else { 6660 r.append(' '); 6661 } 6662 r.append(pg.info.name); 6663 } 6664 } else { 6665 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 6666 + pg.info.packageName + " ignored: original from " 6667 + cur.info.packageName); 6668 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6669 if (r == null) { 6670 r = new StringBuilder(256); 6671 } else { 6672 r.append(' '); 6673 } 6674 r.append("DUP:"); 6675 r.append(pg.info.name); 6676 } 6677 } 6678 } 6679 if (r != null) { 6680 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 6681 } 6682 6683 N = pkg.permissions.size(); 6684 r = null; 6685 for (i=0; i<N; i++) { 6686 PackageParser.Permission p = pkg.permissions.get(i); 6687 ArrayMap<String, BasePermission> permissionMap = 6688 p.tree ? mSettings.mPermissionTrees 6689 : mSettings.mPermissions; 6690 p.group = mPermissionGroups.get(p.info.group); 6691 if (p.info.group == null || p.group != null) { 6692 BasePermission bp = permissionMap.get(p.info.name); 6693 6694 // Allow system apps to redefine non-system permissions 6695 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 6696 final boolean currentOwnerIsSystem = (bp.perm != null 6697 && isSystemApp(bp.perm.owner)); 6698 if (isSystemApp(p.owner)) { 6699 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 6700 // It's a built-in permission and no owner, take ownership now 6701 bp.packageSetting = pkgSetting; 6702 bp.perm = p; 6703 bp.uid = pkg.applicationInfo.uid; 6704 bp.sourcePackage = p.info.packageName; 6705 } else if (!currentOwnerIsSystem) { 6706 String msg = "New decl " + p.owner + " of permission " 6707 + p.info.name + " is system; overriding " + bp.sourcePackage; 6708 reportSettingsProblem(Log.WARN, msg); 6709 bp = null; 6710 } 6711 } 6712 } 6713 6714 if (bp == null) { 6715 bp = new BasePermission(p.info.name, p.info.packageName, 6716 BasePermission.TYPE_NORMAL); 6717 permissionMap.put(p.info.name, bp); 6718 } 6719 6720 if (bp.perm == null) { 6721 if (bp.sourcePackage == null 6722 || bp.sourcePackage.equals(p.info.packageName)) { 6723 BasePermission tree = findPermissionTreeLP(p.info.name); 6724 if (tree == null 6725 || tree.sourcePackage.equals(p.info.packageName)) { 6726 bp.packageSetting = pkgSetting; 6727 bp.perm = p; 6728 bp.uid = pkg.applicationInfo.uid; 6729 bp.sourcePackage = p.info.packageName; 6730 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6731 if (r == null) { 6732 r = new StringBuilder(256); 6733 } else { 6734 r.append(' '); 6735 } 6736 r.append(p.info.name); 6737 } 6738 } else { 6739 Slog.w(TAG, "Permission " + p.info.name + " from package " 6740 + p.info.packageName + " ignored: base tree " 6741 + tree.name + " is from package " 6742 + tree.sourcePackage); 6743 } 6744 } else { 6745 Slog.w(TAG, "Permission " + p.info.name + " from package " 6746 + p.info.packageName + " ignored: original from " 6747 + bp.sourcePackage); 6748 } 6749 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6750 if (r == null) { 6751 r = new StringBuilder(256); 6752 } else { 6753 r.append(' '); 6754 } 6755 r.append("DUP:"); 6756 r.append(p.info.name); 6757 } 6758 if (bp.perm == p) { 6759 bp.protectionLevel = p.info.protectionLevel; 6760 } 6761 } else { 6762 Slog.w(TAG, "Permission " + p.info.name + " from package " 6763 + p.info.packageName + " ignored: no group " 6764 + p.group); 6765 } 6766 } 6767 if (r != null) { 6768 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 6769 } 6770 6771 N = pkg.instrumentation.size(); 6772 r = null; 6773 for (i=0; i<N; i++) { 6774 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6775 a.info.packageName = pkg.applicationInfo.packageName; 6776 a.info.sourceDir = pkg.applicationInfo.sourceDir; 6777 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 6778 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 6779 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 6780 a.info.dataDir = pkg.applicationInfo.dataDir; 6781 6782 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 6783 // need other information about the application, like the ABI and what not ? 6784 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 6785 mInstrumentation.put(a.getComponentName(), a); 6786 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6787 if (r == null) { 6788 r = new StringBuilder(256); 6789 } else { 6790 r.append(' '); 6791 } 6792 r.append(a.info.name); 6793 } 6794 } 6795 if (r != null) { 6796 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 6797 } 6798 6799 if (pkg.protectedBroadcasts != null) { 6800 N = pkg.protectedBroadcasts.size(); 6801 for (i=0; i<N; i++) { 6802 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 6803 } 6804 } 6805 6806 pkgSetting.setTimeStamp(scanFileTime); 6807 6808 // Create idmap files for pairs of (packages, overlay packages). 6809 // Note: "android", ie framework-res.apk, is handled by native layers. 6810 if (pkg.mOverlayTarget != null) { 6811 // This is an overlay package. 6812 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 6813 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 6814 mOverlays.put(pkg.mOverlayTarget, 6815 new ArrayMap<String, PackageParser.Package>()); 6816 } 6817 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 6818 map.put(pkg.packageName, pkg); 6819 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 6820 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 6821 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6822 "scanPackageLI failed to createIdmap"); 6823 } 6824 } 6825 } else if (mOverlays.containsKey(pkg.packageName) && 6826 !pkg.packageName.equals("android")) { 6827 // This is a regular package, with one or more known overlay packages. 6828 createIdmapsForPackageLI(pkg); 6829 } 6830 } 6831 6832 return pkg; 6833 } 6834 6835 /** 6836 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 6837 * i.e, so that all packages can be run inside a single process if required. 6838 * 6839 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 6840 * this function will either try and make the ABI for all packages in {@code packagesForUser} 6841 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 6842 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 6843 * updating a package that belongs to a shared user. 6844 * 6845 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 6846 * adds unnecessary complexity. 6847 */ 6848 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 6849 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { 6850 String requiredInstructionSet = null; 6851 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 6852 requiredInstructionSet = VMRuntime.getInstructionSet( 6853 scannedPackage.applicationInfo.primaryCpuAbi); 6854 } 6855 6856 PackageSetting requirer = null; 6857 for (PackageSetting ps : packagesForUser) { 6858 // If packagesForUser contains scannedPackage, we skip it. This will happen 6859 // when scannedPackage is an update of an existing package. Without this check, 6860 // we will never be able to change the ABI of any package belonging to a shared 6861 // user, even if it's compatible with other packages. 6862 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6863 if (ps.primaryCpuAbiString == null) { 6864 continue; 6865 } 6866 6867 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 6868 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 6869 // We have a mismatch between instruction sets (say arm vs arm64) warn about 6870 // this but there's not much we can do. 6871 String errorMessage = "Instruction set mismatch, " 6872 + ((requirer == null) ? "[caller]" : requirer) 6873 + " requires " + requiredInstructionSet + " whereas " + ps 6874 + " requires " + instructionSet; 6875 Slog.w(TAG, errorMessage); 6876 } 6877 6878 if (requiredInstructionSet == null) { 6879 requiredInstructionSet = instructionSet; 6880 requirer = ps; 6881 } 6882 } 6883 } 6884 6885 if (requiredInstructionSet != null) { 6886 String adjustedAbi; 6887 if (requirer != null) { 6888 // requirer != null implies that either scannedPackage was null or that scannedPackage 6889 // did not require an ABI, in which case we have to adjust scannedPackage to match 6890 // the ABI of the set (which is the same as requirer's ABI) 6891 adjustedAbi = requirer.primaryCpuAbiString; 6892 if (scannedPackage != null) { 6893 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 6894 } 6895 } else { 6896 // requirer == null implies that we're updating all ABIs in the set to 6897 // match scannedPackage. 6898 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 6899 } 6900 6901 for (PackageSetting ps : packagesForUser) { 6902 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6903 if (ps.primaryCpuAbiString != null) { 6904 continue; 6905 } 6906 6907 ps.primaryCpuAbiString = adjustedAbi; 6908 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 6909 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 6910 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 6911 6912 int result = mPackageDexOptimizer.performDexOpt(ps.pkg, 6913 null /* instruction sets */, forceDexOpt, deferDexOpt, true); 6914 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6915 ps.primaryCpuAbiString = null; 6916 ps.pkg.applicationInfo.primaryCpuAbi = null; 6917 return; 6918 } else { 6919 mInstaller.rmdex(ps.codePathString, 6920 getDexCodeInstructionSet(getPreferredInstructionSet())); 6921 } 6922 } 6923 } 6924 } 6925 } 6926 } 6927 6928 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 6929 synchronized (mPackages) { 6930 mResolverReplaced = true; 6931 // Set up information for custom user intent resolution activity. 6932 mResolveActivity.applicationInfo = pkg.applicationInfo; 6933 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 6934 mResolveActivity.packageName = pkg.applicationInfo.packageName; 6935 mResolveActivity.processName = pkg.applicationInfo.packageName; 6936 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6937 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 6938 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 6939 mResolveActivity.theme = 0; 6940 mResolveActivity.exported = true; 6941 mResolveActivity.enabled = true; 6942 mResolveInfo.activityInfo = mResolveActivity; 6943 mResolveInfo.priority = 0; 6944 mResolveInfo.preferredOrder = 0; 6945 mResolveInfo.match = 0; 6946 mResolveComponentName = mCustomResolverComponentName; 6947 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 6948 mResolveComponentName); 6949 } 6950 } 6951 6952 private static String calculateBundledApkRoot(final String codePathString) { 6953 final File codePath = new File(codePathString); 6954 final File codeRoot; 6955 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 6956 codeRoot = Environment.getRootDirectory(); 6957 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 6958 codeRoot = Environment.getOemDirectory(); 6959 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 6960 codeRoot = Environment.getVendorDirectory(); 6961 } else { 6962 // Unrecognized code path; take its top real segment as the apk root: 6963 // e.g. /something/app/blah.apk => /something 6964 try { 6965 File f = codePath.getCanonicalFile(); 6966 File parent = f.getParentFile(); // non-null because codePath is a file 6967 File tmp; 6968 while ((tmp = parent.getParentFile()) != null) { 6969 f = parent; 6970 parent = tmp; 6971 } 6972 codeRoot = f; 6973 Slog.w(TAG, "Unrecognized code path " 6974 + codePath + " - using " + codeRoot); 6975 } catch (IOException e) { 6976 // Can't canonicalize the code path -- shenanigans? 6977 Slog.w(TAG, "Can't canonicalize code path " + codePath); 6978 return Environment.getRootDirectory().getPath(); 6979 } 6980 } 6981 return codeRoot.getPath(); 6982 } 6983 6984 /** 6985 * Derive and set the location of native libraries for the given package, 6986 * which varies depending on where and how the package was installed. 6987 */ 6988 private void setNativeLibraryPaths(PackageParser.Package pkg) { 6989 final ApplicationInfo info = pkg.applicationInfo; 6990 final String codePath = pkg.codePath; 6991 final File codeFile = new File(codePath); 6992 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 6993 final boolean asecApp = info.isForwardLocked() || isExternal(info); 6994 6995 info.nativeLibraryRootDir = null; 6996 info.nativeLibraryRootRequiresIsa = false; 6997 info.nativeLibraryDir = null; 6998 info.secondaryNativeLibraryDir = null; 6999 7000 if (isApkFile(codeFile)) { 7001 // Monolithic install 7002 if (bundledApp) { 7003 // If "/system/lib64/apkname" exists, assume that is the per-package 7004 // native library directory to use; otherwise use "/system/lib/apkname". 7005 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 7006 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 7007 getPrimaryInstructionSet(info)); 7008 7009 // This is a bundled system app so choose the path based on the ABI. 7010 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 7011 // is just the default path. 7012 final String apkName = deriveCodePathName(codePath); 7013 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 7014 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 7015 apkName).getAbsolutePath(); 7016 7017 if (info.secondaryCpuAbi != null) { 7018 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 7019 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 7020 secondaryLibDir, apkName).getAbsolutePath(); 7021 } 7022 } else if (asecApp) { 7023 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 7024 .getAbsolutePath(); 7025 } else { 7026 final String apkName = deriveCodePathName(codePath); 7027 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 7028 .getAbsolutePath(); 7029 } 7030 7031 info.nativeLibraryRootRequiresIsa = false; 7032 info.nativeLibraryDir = info.nativeLibraryRootDir; 7033 } else { 7034 // Cluster install 7035 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 7036 info.nativeLibraryRootRequiresIsa = true; 7037 7038 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 7039 getPrimaryInstructionSet(info)).getAbsolutePath(); 7040 7041 if (info.secondaryCpuAbi != null) { 7042 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 7043 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 7044 } 7045 } 7046 } 7047 7048 /** 7049 * Calculate the abis and roots for a bundled app. These can uniquely 7050 * be determined from the contents of the system partition, i.e whether 7051 * it contains 64 or 32 bit shared libraries etc. We do not validate any 7052 * of this information, and instead assume that the system was built 7053 * sensibly. 7054 */ 7055 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 7056 PackageSetting pkgSetting) { 7057 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 7058 7059 // If "/system/lib64/apkname" exists, assume that is the per-package 7060 // native library directory to use; otherwise use "/system/lib/apkname". 7061 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 7062 setBundledAppAbi(pkg, apkRoot, apkName); 7063 // pkgSetting might be null during rescan following uninstall of updates 7064 // to a bundled app, so accommodate that possibility. The settings in 7065 // that case will be established later from the parsed package. 7066 // 7067 // If the settings aren't null, sync them up with what we've just derived. 7068 // note that apkRoot isn't stored in the package settings. 7069 if (pkgSetting != null) { 7070 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7071 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7072 } 7073 } 7074 7075 /** 7076 * Deduces the ABI of a bundled app and sets the relevant fields on the 7077 * parsed pkg object. 7078 * 7079 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 7080 * under which system libraries are installed. 7081 * @param apkName the name of the installed package. 7082 */ 7083 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 7084 final File codeFile = new File(pkg.codePath); 7085 7086 final boolean has64BitLibs; 7087 final boolean has32BitLibs; 7088 if (isApkFile(codeFile)) { 7089 // Monolithic install 7090 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 7091 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 7092 } else { 7093 // Cluster install 7094 final File rootDir = new File(codeFile, LIB_DIR_NAME); 7095 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 7096 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 7097 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 7098 has64BitLibs = (new File(rootDir, isa)).exists(); 7099 } else { 7100 has64BitLibs = false; 7101 } 7102 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 7103 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 7104 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 7105 has32BitLibs = (new File(rootDir, isa)).exists(); 7106 } else { 7107 has32BitLibs = false; 7108 } 7109 } 7110 7111 if (has64BitLibs && !has32BitLibs) { 7112 // The package has 64 bit libs, but not 32 bit libs. Its primary 7113 // ABI should be 64 bit. We can safely assume here that the bundled 7114 // native libraries correspond to the most preferred ABI in the list. 7115 7116 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7117 pkg.applicationInfo.secondaryCpuAbi = null; 7118 } else if (has32BitLibs && !has64BitLibs) { 7119 // The package has 32 bit libs but not 64 bit libs. Its primary 7120 // ABI should be 32 bit. 7121 7122 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7123 pkg.applicationInfo.secondaryCpuAbi = null; 7124 } else if (has32BitLibs && has64BitLibs) { 7125 // The application has both 64 and 32 bit bundled libraries. We check 7126 // here that the app declares multiArch support, and warn if it doesn't. 7127 // 7128 // We will be lenient here and record both ABIs. The primary will be the 7129 // ABI that's higher on the list, i.e, a device that's configured to prefer 7130 // 64 bit apps will see a 64 bit primary ABI, 7131 7132 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 7133 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 7134 } 7135 7136 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 7137 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7138 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7139 } else { 7140 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7141 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7142 } 7143 } else { 7144 pkg.applicationInfo.primaryCpuAbi = null; 7145 pkg.applicationInfo.secondaryCpuAbi = null; 7146 } 7147 } 7148 7149 private void killApplication(String pkgName, int appId, String reason) { 7150 // Request the ActivityManager to kill the process(only for existing packages) 7151 // so that we do not end up in a confused state while the user is still using the older 7152 // version of the application while the new one gets installed. 7153 IActivityManager am = ActivityManagerNative.getDefault(); 7154 if (am != null) { 7155 try { 7156 am.killApplicationWithAppId(pkgName, appId, reason); 7157 } catch (RemoteException e) { 7158 } 7159 } 7160 } 7161 7162 void removePackageLI(PackageSetting ps, boolean chatty) { 7163 if (DEBUG_INSTALL) { 7164 if (chatty) 7165 Log.d(TAG, "Removing package " + ps.name); 7166 } 7167 7168 // writer 7169 synchronized (mPackages) { 7170 mPackages.remove(ps.name); 7171 final PackageParser.Package pkg = ps.pkg; 7172 if (pkg != null) { 7173 cleanPackageDataStructuresLILPw(pkg, chatty); 7174 } 7175 } 7176 } 7177 7178 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 7179 if (DEBUG_INSTALL) { 7180 if (chatty) 7181 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 7182 } 7183 7184 // writer 7185 synchronized (mPackages) { 7186 mPackages.remove(pkg.applicationInfo.packageName); 7187 cleanPackageDataStructuresLILPw(pkg, chatty); 7188 } 7189 } 7190 7191 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 7192 int N = pkg.providers.size(); 7193 StringBuilder r = null; 7194 int i; 7195 for (i=0; i<N; i++) { 7196 PackageParser.Provider p = pkg.providers.get(i); 7197 mProviders.removeProvider(p); 7198 if (p.info.authority == null) { 7199 7200 /* There was another ContentProvider with this authority when 7201 * this app was installed so this authority is null, 7202 * Ignore it as we don't have to unregister the provider. 7203 */ 7204 continue; 7205 } 7206 String names[] = p.info.authority.split(";"); 7207 for (int j = 0; j < names.length; j++) { 7208 if (mProvidersByAuthority.get(names[j]) == p) { 7209 mProvidersByAuthority.remove(names[j]); 7210 if (DEBUG_REMOVE) { 7211 if (chatty) 7212 Log.d(TAG, "Unregistered content provider: " + names[j] 7213 + ", className = " + p.info.name + ", isSyncable = " 7214 + p.info.isSyncable); 7215 } 7216 } 7217 } 7218 if (DEBUG_REMOVE && chatty) { 7219 if (r == null) { 7220 r = new StringBuilder(256); 7221 } else { 7222 r.append(' '); 7223 } 7224 r.append(p.info.name); 7225 } 7226 } 7227 if (r != null) { 7228 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 7229 } 7230 7231 N = pkg.services.size(); 7232 r = null; 7233 for (i=0; i<N; i++) { 7234 PackageParser.Service s = pkg.services.get(i); 7235 mServices.removeService(s); 7236 if (chatty) { 7237 if (r == null) { 7238 r = new StringBuilder(256); 7239 } else { 7240 r.append(' '); 7241 } 7242 r.append(s.info.name); 7243 } 7244 } 7245 if (r != null) { 7246 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 7247 } 7248 7249 N = pkg.receivers.size(); 7250 r = null; 7251 for (i=0; i<N; i++) { 7252 PackageParser.Activity a = pkg.receivers.get(i); 7253 mReceivers.removeActivity(a, "receiver"); 7254 if (DEBUG_REMOVE && chatty) { 7255 if (r == null) { 7256 r = new StringBuilder(256); 7257 } else { 7258 r.append(' '); 7259 } 7260 r.append(a.info.name); 7261 } 7262 } 7263 if (r != null) { 7264 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 7265 } 7266 7267 N = pkg.activities.size(); 7268 r = null; 7269 for (i=0; i<N; i++) { 7270 PackageParser.Activity a = pkg.activities.get(i); 7271 mActivities.removeActivity(a, "activity"); 7272 if (DEBUG_REMOVE && chatty) { 7273 if (r == null) { 7274 r = new StringBuilder(256); 7275 } else { 7276 r.append(' '); 7277 } 7278 r.append(a.info.name); 7279 } 7280 } 7281 if (r != null) { 7282 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 7283 } 7284 7285 N = pkg.permissions.size(); 7286 r = null; 7287 for (i=0; i<N; i++) { 7288 PackageParser.Permission p = pkg.permissions.get(i); 7289 BasePermission bp = mSettings.mPermissions.get(p.info.name); 7290 if (bp == null) { 7291 bp = mSettings.mPermissionTrees.get(p.info.name); 7292 } 7293 if (bp != null && bp.perm == p) { 7294 bp.perm = null; 7295 if (DEBUG_REMOVE && chatty) { 7296 if (r == null) { 7297 r = new StringBuilder(256); 7298 } else { 7299 r.append(' '); 7300 } 7301 r.append(p.info.name); 7302 } 7303 } 7304 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7305 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 7306 if (appOpPerms != null) { 7307 appOpPerms.remove(pkg.packageName); 7308 } 7309 } 7310 } 7311 if (r != null) { 7312 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7313 } 7314 7315 N = pkg.requestedPermissions.size(); 7316 r = null; 7317 for (i=0; i<N; i++) { 7318 String perm = pkg.requestedPermissions.get(i); 7319 BasePermission bp = mSettings.mPermissions.get(perm); 7320 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7321 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 7322 if (appOpPerms != null) { 7323 appOpPerms.remove(pkg.packageName); 7324 if (appOpPerms.isEmpty()) { 7325 mAppOpPermissionPackages.remove(perm); 7326 } 7327 } 7328 } 7329 } 7330 if (r != null) { 7331 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7332 } 7333 7334 N = pkg.instrumentation.size(); 7335 r = null; 7336 for (i=0; i<N; i++) { 7337 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 7338 mInstrumentation.remove(a.getComponentName()); 7339 if (DEBUG_REMOVE && chatty) { 7340 if (r == null) { 7341 r = new StringBuilder(256); 7342 } else { 7343 r.append(' '); 7344 } 7345 r.append(a.info.name); 7346 } 7347 } 7348 if (r != null) { 7349 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 7350 } 7351 7352 r = null; 7353 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7354 // Only system apps can hold shared libraries. 7355 if (pkg.libraryNames != null) { 7356 for (i=0; i<pkg.libraryNames.size(); i++) { 7357 String name = pkg.libraryNames.get(i); 7358 SharedLibraryEntry cur = mSharedLibraries.get(name); 7359 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 7360 mSharedLibraries.remove(name); 7361 if (DEBUG_REMOVE && chatty) { 7362 if (r == null) { 7363 r = new StringBuilder(256); 7364 } else { 7365 r.append(' '); 7366 } 7367 r.append(name); 7368 } 7369 } 7370 } 7371 } 7372 } 7373 if (r != null) { 7374 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 7375 } 7376 } 7377 7378 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 7379 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 7380 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 7381 return true; 7382 } 7383 } 7384 return false; 7385 } 7386 7387 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 7388 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 7389 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 7390 7391 private void updatePermissionsLPw(String changingPkg, 7392 PackageParser.Package pkgInfo, int flags) { 7393 // Make sure there are no dangling permission trees. 7394 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 7395 while (it.hasNext()) { 7396 final BasePermission bp = it.next(); 7397 if (bp.packageSetting == null) { 7398 // We may not yet have parsed the package, so just see if 7399 // we still know about its settings. 7400 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7401 } 7402 if (bp.packageSetting == null) { 7403 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 7404 + " from package " + bp.sourcePackage); 7405 it.remove(); 7406 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7407 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7408 Slog.i(TAG, "Removing old permission tree: " + bp.name 7409 + " from package " + bp.sourcePackage); 7410 flags |= UPDATE_PERMISSIONS_ALL; 7411 it.remove(); 7412 } 7413 } 7414 } 7415 7416 // Make sure all dynamic permissions have been assigned to a package, 7417 // and make sure there are no dangling permissions. 7418 it = mSettings.mPermissions.values().iterator(); 7419 while (it.hasNext()) { 7420 final BasePermission bp = it.next(); 7421 if (bp.type == BasePermission.TYPE_DYNAMIC) { 7422 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 7423 + bp.name + " pkg=" + bp.sourcePackage 7424 + " info=" + bp.pendingInfo); 7425 if (bp.packageSetting == null && bp.pendingInfo != null) { 7426 final BasePermission tree = findPermissionTreeLP(bp.name); 7427 if (tree != null && tree.perm != null) { 7428 bp.packageSetting = tree.packageSetting; 7429 bp.perm = new PackageParser.Permission(tree.perm.owner, 7430 new PermissionInfo(bp.pendingInfo)); 7431 bp.perm.info.packageName = tree.perm.info.packageName; 7432 bp.perm.info.name = bp.name; 7433 bp.uid = tree.uid; 7434 } 7435 } 7436 } 7437 if (bp.packageSetting == null) { 7438 // We may not yet have parsed the package, so just see if 7439 // we still know about its settings. 7440 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7441 } 7442 if (bp.packageSetting == null) { 7443 Slog.w(TAG, "Removing dangling permission: " + bp.name 7444 + " from package " + bp.sourcePackage); 7445 it.remove(); 7446 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7447 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7448 Slog.i(TAG, "Removing old permission: " + bp.name 7449 + " from package " + bp.sourcePackage); 7450 flags |= UPDATE_PERMISSIONS_ALL; 7451 it.remove(); 7452 } 7453 } 7454 } 7455 7456 // Now update the permissions for all packages, in particular 7457 // replace the granted permissions of the system packages. 7458 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 7459 for (PackageParser.Package pkg : mPackages.values()) { 7460 if (pkg != pkgInfo) { 7461 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0, 7462 changingPkg); 7463 } 7464 } 7465 } 7466 7467 if (pkgInfo != null) { 7468 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg); 7469 } 7470 } 7471 7472 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 7473 String packageOfInterest) { 7474 // IMPORTANT: There are two types of permissions: install and runtime. 7475 // Install time permissions are granted when the app is installed to 7476 // all device users and users added in the future. Runtime permissions 7477 // are granted at runtime explicitly to specific users. Normal and signature 7478 // protected permissions are install time permissions. Dangerous permissions 7479 // are install permissions if the app's target SDK is Lollipop MR1 or older, 7480 // otherwise they are runtime permissions. This function does not manage 7481 // runtime permissions except for the case an app targeting Lollipop MR1 7482 // being upgraded to target a newer SDK, in which case dangerous permissions 7483 // are transformed from install time to runtime ones. 7484 7485 final PackageSetting ps = (PackageSetting) pkg.mExtras; 7486 if (ps == null) { 7487 return; 7488 } 7489 7490 PermissionsState permissionsState = ps.getPermissionsState(); 7491 PermissionsState origPermissions = permissionsState; 7492 7493 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 7494 7495 int[] upgradeUserIds = PermissionsState.USERS_NONE; 7496 int[] changedRuntimePermissionUserIds = PermissionsState.USERS_NONE; 7497 7498 boolean changedInstallPermission = false; 7499 7500 if (replace) { 7501 ps.installPermissionsFixed = false; 7502 if (!ps.isSharedUser()) { 7503 origPermissions = new PermissionsState(permissionsState); 7504 permissionsState.reset(); 7505 } 7506 } 7507 7508 permissionsState.setGlobalGids(mGlobalGids); 7509 7510 final int N = pkg.requestedPermissions.size(); 7511 for (int i=0; i<N; i++) { 7512 final String name = pkg.requestedPermissions.get(i); 7513 final BasePermission bp = mSettings.mPermissions.get(name); 7514 7515 if (DEBUG_INSTALL) { 7516 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 7517 } 7518 7519 if (bp == null || bp.packageSetting == null) { 7520 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7521 Slog.w(TAG, "Unknown permission " + name 7522 + " in package " + pkg.packageName); 7523 } 7524 continue; 7525 } 7526 7527 final String perm = bp.name; 7528 boolean allowedSig = false; 7529 int grant = GRANT_DENIED; 7530 7531 // Keep track of app op permissions. 7532 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7533 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 7534 if (pkgs == null) { 7535 pkgs = new ArraySet<>(); 7536 mAppOpPermissionPackages.put(bp.name, pkgs); 7537 } 7538 pkgs.add(pkg.packageName); 7539 } 7540 7541 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 7542 switch (level) { 7543 case PermissionInfo.PROTECTION_NORMAL: { 7544 // For all apps normal permissions are install time ones. 7545 grant = GRANT_INSTALL; 7546 } break; 7547 7548 case PermissionInfo.PROTECTION_DANGEROUS: { 7549 if (!RUNTIME_PERMISSIONS_ENABLED 7550 || pkg.applicationInfo.targetSdkVersion 7551 <= Build.VERSION_CODES.LOLLIPOP_MR1) { 7552 // For legacy apps dangerous permissions are install time ones. 7553 grant = GRANT_INSTALL; 7554 } else if (ps.isSystem()) { 7555 final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds(); 7556 if (origPermissions.hasInstallPermission(bp.name)) { 7557 // If a system app had an install permission, then the app was 7558 // upgraded and we grant the permissions as runtime to all users. 7559 grant = GRANT_UPGRADE; 7560 upgradeUserIds = currentUserIds; 7561 } else if (!Arrays.equals(updatedUserIds, currentUserIds)) { 7562 // If users changed since the last permissions update for a 7563 // system app, we grant the permission as runtime to the new users. 7564 grant = GRANT_UPGRADE; 7565 upgradeUserIds = currentUserIds; 7566 for (int userId : updatedUserIds) { 7567 upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId); 7568 } 7569 } else { 7570 // Otherwise, we grant the permission as runtime if the app 7571 // already had it, i.e. we preserve runtime permissions. 7572 grant = GRANT_RUNTIME; 7573 } 7574 } else if (origPermissions.hasInstallPermission(bp.name)) { 7575 // For legacy apps that became modern, install becomes runtime. 7576 grant = GRANT_UPGRADE; 7577 upgradeUserIds = currentUserIds; 7578 } else if (replace) { 7579 // For upgraded modern apps keep runtime permissions unchanged. 7580 grant = GRANT_RUNTIME; 7581 } 7582 } break; 7583 7584 case PermissionInfo.PROTECTION_SIGNATURE: { 7585 // For all apps signature permissions are install time ones. 7586 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 7587 if (allowedSig) { 7588 grant = GRANT_INSTALL; 7589 } 7590 } break; 7591 } 7592 7593 if (DEBUG_INSTALL) { 7594 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 7595 } 7596 7597 if (grant != GRANT_DENIED) { 7598 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 7599 // If this is an existing, non-system package, then 7600 // we can't add any new permissions to it. 7601 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 7602 // Except... if this is a permission that was added 7603 // to the platform (note: need to only do this when 7604 // updating the platform). 7605 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 7606 grant = GRANT_DENIED; 7607 } 7608 } 7609 } 7610 7611 switch (grant) { 7612 case GRANT_INSTALL: { 7613 // Grant an install permission. 7614 if (permissionsState.grantInstallPermission(bp) != 7615 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7616 changedInstallPermission = true; 7617 } 7618 } break; 7619 7620 case GRANT_RUNTIME: { 7621 // Grant previously granted runtime permissions. 7622 for (int userId : UserManagerService.getInstance().getUserIds()) { 7623 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 7624 if (permissionsState.grantRuntimePermission(bp, userId) == 7625 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7626 // If we cannot put the permission as it was, we have to write. 7627 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7628 changedRuntimePermissionUserIds, userId); 7629 } 7630 } 7631 } 7632 } break; 7633 7634 case GRANT_UPGRADE: { 7635 // Grant runtime permissions for a previously held install permission. 7636 permissionsState.revokeInstallPermission(bp); 7637 for (int userId : upgradeUserIds) { 7638 if (permissionsState.grantRuntimePermission(bp, userId) != 7639 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7640 // If we granted the permission, we have to write. 7641 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7642 changedRuntimePermissionUserIds, userId); 7643 } 7644 } 7645 } break; 7646 7647 default: { 7648 if (packageOfInterest == null 7649 || packageOfInterest.equals(pkg.packageName)) { 7650 Slog.w(TAG, "Not granting permission " + perm 7651 + " to package " + pkg.packageName 7652 + " because it was previously installed without"); 7653 } 7654 } break; 7655 } 7656 } else { 7657 if (permissionsState.revokeInstallPermission(bp) != 7658 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7659 changedInstallPermission = true; 7660 Slog.i(TAG, "Un-granting permission " + perm 7661 + " from package " + pkg.packageName 7662 + " (protectionLevel=" + bp.protectionLevel 7663 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7664 + ")"); 7665 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 7666 // Don't print warning for app op permissions, since it is fine for them 7667 // not to be granted, there is a UI for the user to decide. 7668 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7669 Slog.w(TAG, "Not granting permission " + perm 7670 + " to package " + pkg.packageName 7671 + " (protectionLevel=" + bp.protectionLevel 7672 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7673 + ")"); 7674 } 7675 } 7676 } 7677 } 7678 7679 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 7680 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 7681 // This is the first that we have heard about this package, so the 7682 // permissions we have now selected are fixed until explicitly 7683 // changed. 7684 ps.installPermissionsFixed = true; 7685 } 7686 7687 ps.setPermissionsUpdatedForUserIds(currentUserIds); 7688 7689 // Persist the runtime permissions state for users with changes. 7690 if (RUNTIME_PERMISSIONS_ENABLED) { 7691 for (int userId : changedRuntimePermissionUserIds) { 7692 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 7693 } 7694 } 7695 } 7696 7697 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 7698 boolean allowed = false; 7699 final int NP = PackageParser.NEW_PERMISSIONS.length; 7700 for (int ip=0; ip<NP; ip++) { 7701 final PackageParser.NewPermissionInfo npi 7702 = PackageParser.NEW_PERMISSIONS[ip]; 7703 if (npi.name.equals(perm) 7704 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 7705 allowed = true; 7706 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 7707 + pkg.packageName); 7708 break; 7709 } 7710 } 7711 return allowed; 7712 } 7713 7714 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 7715 BasePermission bp, PermissionsState origPermissions) { 7716 boolean allowed; 7717 allowed = (compareSignatures( 7718 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 7719 == PackageManager.SIGNATURE_MATCH) 7720 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 7721 == PackageManager.SIGNATURE_MATCH); 7722 if (!allowed && (bp.protectionLevel 7723 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 7724 if (isSystemApp(pkg)) { 7725 // For updated system applications, a system permission 7726 // is granted only if it had been defined by the original application. 7727 if (pkg.isUpdatedSystemApp()) { 7728 final PackageSetting sysPs = mSettings 7729 .getDisabledSystemPkgLPr(pkg.packageName); 7730 if (sysPs.getPermissionsState().hasInstallPermission(perm)) { 7731 // If the original was granted this permission, we take 7732 // that grant decision as read and propagate it to the 7733 // update. 7734 if (sysPs.isPrivileged()) { 7735 allowed = true; 7736 } 7737 } else { 7738 // The system apk may have been updated with an older 7739 // version of the one on the data partition, but which 7740 // granted a new system permission that it didn't have 7741 // before. In this case we do want to allow the app to 7742 // now get the new permission if the ancestral apk is 7743 // privileged to get it. 7744 if (sysPs.pkg != null && sysPs.isPrivileged()) { 7745 for (int j=0; 7746 j<sysPs.pkg.requestedPermissions.size(); j++) { 7747 if (perm.equals( 7748 sysPs.pkg.requestedPermissions.get(j))) { 7749 allowed = true; 7750 break; 7751 } 7752 } 7753 } 7754 } 7755 } else { 7756 allowed = isPrivilegedApp(pkg); 7757 } 7758 } 7759 } 7760 if (!allowed && (bp.protectionLevel 7761 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 7762 // For development permissions, a development permission 7763 // is granted only if it was already granted. 7764 allowed = origPermissions.hasInstallPermission(perm); 7765 } 7766 return allowed; 7767 } 7768 7769 final class ActivityIntentResolver 7770 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 7771 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7772 boolean defaultOnly, int userId) { 7773 if (!sUserManager.exists(userId)) return null; 7774 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7775 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7776 } 7777 7778 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7779 int userId) { 7780 if (!sUserManager.exists(userId)) return null; 7781 mFlags = flags; 7782 return super.queryIntent(intent, resolvedType, 7783 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7784 } 7785 7786 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7787 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 7788 if (!sUserManager.exists(userId)) return null; 7789 if (packageActivities == null) { 7790 return null; 7791 } 7792 mFlags = flags; 7793 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 7794 final int N = packageActivities.size(); 7795 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 7796 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 7797 7798 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 7799 for (int i = 0; i < N; ++i) { 7800 intentFilters = packageActivities.get(i).intents; 7801 if (intentFilters != null && intentFilters.size() > 0) { 7802 PackageParser.ActivityIntentInfo[] array = 7803 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 7804 intentFilters.toArray(array); 7805 listCut.add(array); 7806 } 7807 } 7808 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7809 } 7810 7811 public final void addActivity(PackageParser.Activity a, String type) { 7812 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 7813 mActivities.put(a.getComponentName(), a); 7814 if (DEBUG_SHOW_INFO) 7815 Log.v( 7816 TAG, " " + type + " " + 7817 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 7818 if (DEBUG_SHOW_INFO) 7819 Log.v(TAG, " Class=" + a.info.name); 7820 final int NI = a.intents.size(); 7821 for (int j=0; j<NI; j++) { 7822 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7823 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 7824 intent.setPriority(0); 7825 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 7826 + a.className + " with priority > 0, forcing to 0"); 7827 } 7828 if (DEBUG_SHOW_INFO) { 7829 Log.v(TAG, " IntentFilter:"); 7830 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7831 } 7832 if (!intent.debugCheck()) { 7833 Log.w(TAG, "==> For Activity " + a.info.name); 7834 } 7835 addFilter(intent); 7836 } 7837 } 7838 7839 public final void removeActivity(PackageParser.Activity a, String type) { 7840 mActivities.remove(a.getComponentName()); 7841 if (DEBUG_SHOW_INFO) { 7842 Log.v(TAG, " " + type + " " 7843 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 7844 : a.info.name) + ":"); 7845 Log.v(TAG, " Class=" + a.info.name); 7846 } 7847 final int NI = a.intents.size(); 7848 for (int j=0; j<NI; j++) { 7849 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7850 if (DEBUG_SHOW_INFO) { 7851 Log.v(TAG, " IntentFilter:"); 7852 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7853 } 7854 removeFilter(intent); 7855 } 7856 } 7857 7858 @Override 7859 protected boolean allowFilterResult( 7860 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 7861 ActivityInfo filterAi = filter.activity.info; 7862 for (int i=dest.size()-1; i>=0; i--) { 7863 ActivityInfo destAi = dest.get(i).activityInfo; 7864 if (destAi.name == filterAi.name 7865 && destAi.packageName == filterAi.packageName) { 7866 return false; 7867 } 7868 } 7869 return true; 7870 } 7871 7872 @Override 7873 protected ActivityIntentInfo[] newArray(int size) { 7874 return new ActivityIntentInfo[size]; 7875 } 7876 7877 @Override 7878 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 7879 if (!sUserManager.exists(userId)) return true; 7880 PackageParser.Package p = filter.activity.owner; 7881 if (p != null) { 7882 PackageSetting ps = (PackageSetting)p.mExtras; 7883 if (ps != null) { 7884 // System apps are never considered stopped for purposes of 7885 // filtering, because there may be no way for the user to 7886 // actually re-launch them. 7887 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 7888 && ps.getStopped(userId); 7889 } 7890 } 7891 return false; 7892 } 7893 7894 @Override 7895 protected boolean isPackageForFilter(String packageName, 7896 PackageParser.ActivityIntentInfo info) { 7897 return packageName.equals(info.activity.owner.packageName); 7898 } 7899 7900 @Override 7901 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 7902 int match, int userId) { 7903 if (!sUserManager.exists(userId)) return null; 7904 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 7905 return null; 7906 } 7907 final PackageParser.Activity activity = info.activity; 7908 if (mSafeMode && (activity.info.applicationInfo.flags 7909 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7910 return null; 7911 } 7912 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 7913 if (ps == null) { 7914 return null; 7915 } 7916 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 7917 ps.readUserState(userId), userId); 7918 if (ai == null) { 7919 return null; 7920 } 7921 final ResolveInfo res = new ResolveInfo(); 7922 res.activityInfo = ai; 7923 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 7924 res.filter = info; 7925 } 7926 if (info != null) { 7927 res.handleAllWebDataURI = info.handleAllWebDataURI(); 7928 } 7929 res.priority = info.getPriority(); 7930 res.preferredOrder = activity.owner.mPreferredOrder; 7931 //System.out.println("Result: " + res.activityInfo.className + 7932 // " = " + res.priority); 7933 res.match = match; 7934 res.isDefault = info.hasDefault; 7935 res.labelRes = info.labelRes; 7936 res.nonLocalizedLabel = info.nonLocalizedLabel; 7937 if (userNeedsBadging(userId)) { 7938 res.noResourceId = true; 7939 } else { 7940 res.icon = info.icon; 7941 } 7942 res.system = res.activityInfo.applicationInfo.isSystemApp(); 7943 return res; 7944 } 7945 7946 @Override 7947 protected void sortResults(List<ResolveInfo> results) { 7948 Collections.sort(results, mResolvePrioritySorter); 7949 } 7950 7951 @Override 7952 protected void dumpFilter(PrintWriter out, String prefix, 7953 PackageParser.ActivityIntentInfo filter) { 7954 out.print(prefix); out.print( 7955 Integer.toHexString(System.identityHashCode(filter.activity))); 7956 out.print(' '); 7957 filter.activity.printComponentShortName(out); 7958 out.print(" filter "); 7959 out.println(Integer.toHexString(System.identityHashCode(filter))); 7960 } 7961 7962 @Override 7963 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 7964 return filter.activity; 7965 } 7966 7967 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 7968 PackageParser.Activity activity = (PackageParser.Activity)label; 7969 out.print(prefix); out.print( 7970 Integer.toHexString(System.identityHashCode(activity))); 7971 out.print(' '); 7972 activity.printComponentShortName(out); 7973 if (count > 1) { 7974 out.print(" ("); out.print(count); out.print(" filters)"); 7975 } 7976 out.println(); 7977 } 7978 7979// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 7980// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 7981// final List<ResolveInfo> retList = Lists.newArrayList(); 7982// while (i.hasNext()) { 7983// final ResolveInfo resolveInfo = i.next(); 7984// if (isEnabledLP(resolveInfo.activityInfo)) { 7985// retList.add(resolveInfo); 7986// } 7987// } 7988// return retList; 7989// } 7990 7991 // Keys are String (activity class name), values are Activity. 7992 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 7993 = new ArrayMap<ComponentName, PackageParser.Activity>(); 7994 private int mFlags; 7995 } 7996 7997 private final class ServiceIntentResolver 7998 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 7999 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8000 boolean defaultOnly, int userId) { 8001 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8002 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8003 } 8004 8005 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8006 int userId) { 8007 if (!sUserManager.exists(userId)) return null; 8008 mFlags = flags; 8009 return super.queryIntent(intent, resolvedType, 8010 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8011 } 8012 8013 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8014 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 8015 if (!sUserManager.exists(userId)) return null; 8016 if (packageServices == null) { 8017 return null; 8018 } 8019 mFlags = flags; 8020 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8021 final int N = packageServices.size(); 8022 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 8023 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 8024 8025 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 8026 for (int i = 0; i < N; ++i) { 8027 intentFilters = packageServices.get(i).intents; 8028 if (intentFilters != null && intentFilters.size() > 0) { 8029 PackageParser.ServiceIntentInfo[] array = 8030 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 8031 intentFilters.toArray(array); 8032 listCut.add(array); 8033 } 8034 } 8035 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8036 } 8037 8038 public final void addService(PackageParser.Service s) { 8039 mServices.put(s.getComponentName(), s); 8040 if (DEBUG_SHOW_INFO) { 8041 Log.v(TAG, " " 8042 + (s.info.nonLocalizedLabel != null 8043 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8044 Log.v(TAG, " Class=" + s.info.name); 8045 } 8046 final int NI = s.intents.size(); 8047 int j; 8048 for (j=0; j<NI; j++) { 8049 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8050 if (DEBUG_SHOW_INFO) { 8051 Log.v(TAG, " IntentFilter:"); 8052 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8053 } 8054 if (!intent.debugCheck()) { 8055 Log.w(TAG, "==> For Service " + s.info.name); 8056 } 8057 addFilter(intent); 8058 } 8059 } 8060 8061 public final void removeService(PackageParser.Service s) { 8062 mServices.remove(s.getComponentName()); 8063 if (DEBUG_SHOW_INFO) { 8064 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 8065 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8066 Log.v(TAG, " Class=" + s.info.name); 8067 } 8068 final int NI = s.intents.size(); 8069 int j; 8070 for (j=0; j<NI; j++) { 8071 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8072 if (DEBUG_SHOW_INFO) { 8073 Log.v(TAG, " IntentFilter:"); 8074 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8075 } 8076 removeFilter(intent); 8077 } 8078 } 8079 8080 @Override 8081 protected boolean allowFilterResult( 8082 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 8083 ServiceInfo filterSi = filter.service.info; 8084 for (int i=dest.size()-1; i>=0; i--) { 8085 ServiceInfo destAi = dest.get(i).serviceInfo; 8086 if (destAi.name == filterSi.name 8087 && destAi.packageName == filterSi.packageName) { 8088 return false; 8089 } 8090 } 8091 return true; 8092 } 8093 8094 @Override 8095 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 8096 return new PackageParser.ServiceIntentInfo[size]; 8097 } 8098 8099 @Override 8100 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 8101 if (!sUserManager.exists(userId)) return true; 8102 PackageParser.Package p = filter.service.owner; 8103 if (p != null) { 8104 PackageSetting ps = (PackageSetting)p.mExtras; 8105 if (ps != null) { 8106 // System apps are never considered stopped for purposes of 8107 // filtering, because there may be no way for the user to 8108 // actually re-launch them. 8109 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8110 && ps.getStopped(userId); 8111 } 8112 } 8113 return false; 8114 } 8115 8116 @Override 8117 protected boolean isPackageForFilter(String packageName, 8118 PackageParser.ServiceIntentInfo info) { 8119 return packageName.equals(info.service.owner.packageName); 8120 } 8121 8122 @Override 8123 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 8124 int match, int userId) { 8125 if (!sUserManager.exists(userId)) return null; 8126 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 8127 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 8128 return null; 8129 } 8130 final PackageParser.Service service = info.service; 8131 if (mSafeMode && (service.info.applicationInfo.flags 8132 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8133 return null; 8134 } 8135 PackageSetting ps = (PackageSetting) service.owner.mExtras; 8136 if (ps == null) { 8137 return null; 8138 } 8139 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 8140 ps.readUserState(userId), userId); 8141 if (si == null) { 8142 return null; 8143 } 8144 final ResolveInfo res = new ResolveInfo(); 8145 res.serviceInfo = si; 8146 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 8147 res.filter = filter; 8148 } 8149 res.priority = info.getPriority(); 8150 res.preferredOrder = service.owner.mPreferredOrder; 8151 res.match = match; 8152 res.isDefault = info.hasDefault; 8153 res.labelRes = info.labelRes; 8154 res.nonLocalizedLabel = info.nonLocalizedLabel; 8155 res.icon = info.icon; 8156 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 8157 return res; 8158 } 8159 8160 @Override 8161 protected void sortResults(List<ResolveInfo> results) { 8162 Collections.sort(results, mResolvePrioritySorter); 8163 } 8164 8165 @Override 8166 protected void dumpFilter(PrintWriter out, String prefix, 8167 PackageParser.ServiceIntentInfo filter) { 8168 out.print(prefix); out.print( 8169 Integer.toHexString(System.identityHashCode(filter.service))); 8170 out.print(' '); 8171 filter.service.printComponentShortName(out); 8172 out.print(" filter "); 8173 out.println(Integer.toHexString(System.identityHashCode(filter))); 8174 } 8175 8176 @Override 8177 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 8178 return filter.service; 8179 } 8180 8181 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8182 PackageParser.Service service = (PackageParser.Service)label; 8183 out.print(prefix); out.print( 8184 Integer.toHexString(System.identityHashCode(service))); 8185 out.print(' '); 8186 service.printComponentShortName(out); 8187 if (count > 1) { 8188 out.print(" ("); out.print(count); out.print(" filters)"); 8189 } 8190 out.println(); 8191 } 8192 8193// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8194// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8195// final List<ResolveInfo> retList = Lists.newArrayList(); 8196// while (i.hasNext()) { 8197// final ResolveInfo resolveInfo = (ResolveInfo) i; 8198// if (isEnabledLP(resolveInfo.serviceInfo)) { 8199// retList.add(resolveInfo); 8200// } 8201// } 8202// return retList; 8203// } 8204 8205 // Keys are String (activity class name), values are Activity. 8206 private final ArrayMap<ComponentName, PackageParser.Service> mServices 8207 = new ArrayMap<ComponentName, PackageParser.Service>(); 8208 private int mFlags; 8209 }; 8210 8211 private final class ProviderIntentResolver 8212 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 8213 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8214 boolean defaultOnly, int userId) { 8215 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8216 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8217 } 8218 8219 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8220 int userId) { 8221 if (!sUserManager.exists(userId)) 8222 return null; 8223 mFlags = flags; 8224 return super.queryIntent(intent, resolvedType, 8225 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8226 } 8227 8228 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8229 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 8230 if (!sUserManager.exists(userId)) 8231 return null; 8232 if (packageProviders == null) { 8233 return null; 8234 } 8235 mFlags = flags; 8236 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 8237 final int N = packageProviders.size(); 8238 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 8239 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 8240 8241 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 8242 for (int i = 0; i < N; ++i) { 8243 intentFilters = packageProviders.get(i).intents; 8244 if (intentFilters != null && intentFilters.size() > 0) { 8245 PackageParser.ProviderIntentInfo[] array = 8246 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 8247 intentFilters.toArray(array); 8248 listCut.add(array); 8249 } 8250 } 8251 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8252 } 8253 8254 public final void addProvider(PackageParser.Provider p) { 8255 if (mProviders.containsKey(p.getComponentName())) { 8256 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 8257 return; 8258 } 8259 8260 mProviders.put(p.getComponentName(), p); 8261 if (DEBUG_SHOW_INFO) { 8262 Log.v(TAG, " " 8263 + (p.info.nonLocalizedLabel != null 8264 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8265 Log.v(TAG, " Class=" + p.info.name); 8266 } 8267 final int NI = p.intents.size(); 8268 int j; 8269 for (j = 0; j < NI; j++) { 8270 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8271 if (DEBUG_SHOW_INFO) { 8272 Log.v(TAG, " IntentFilter:"); 8273 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8274 } 8275 if (!intent.debugCheck()) { 8276 Log.w(TAG, "==> For Provider " + p.info.name); 8277 } 8278 addFilter(intent); 8279 } 8280 } 8281 8282 public final void removeProvider(PackageParser.Provider p) { 8283 mProviders.remove(p.getComponentName()); 8284 if (DEBUG_SHOW_INFO) { 8285 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 8286 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8287 Log.v(TAG, " Class=" + p.info.name); 8288 } 8289 final int NI = p.intents.size(); 8290 int j; 8291 for (j = 0; j < NI; j++) { 8292 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8293 if (DEBUG_SHOW_INFO) { 8294 Log.v(TAG, " IntentFilter:"); 8295 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8296 } 8297 removeFilter(intent); 8298 } 8299 } 8300 8301 @Override 8302 protected boolean allowFilterResult( 8303 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 8304 ProviderInfo filterPi = filter.provider.info; 8305 for (int i = dest.size() - 1; i >= 0; i--) { 8306 ProviderInfo destPi = dest.get(i).providerInfo; 8307 if (destPi.name == filterPi.name 8308 && destPi.packageName == filterPi.packageName) { 8309 return false; 8310 } 8311 } 8312 return true; 8313 } 8314 8315 @Override 8316 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 8317 return new PackageParser.ProviderIntentInfo[size]; 8318 } 8319 8320 @Override 8321 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 8322 if (!sUserManager.exists(userId)) 8323 return true; 8324 PackageParser.Package p = filter.provider.owner; 8325 if (p != null) { 8326 PackageSetting ps = (PackageSetting) p.mExtras; 8327 if (ps != null) { 8328 // System apps are never considered stopped for purposes of 8329 // filtering, because there may be no way for the user to 8330 // actually re-launch them. 8331 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8332 && ps.getStopped(userId); 8333 } 8334 } 8335 return false; 8336 } 8337 8338 @Override 8339 protected boolean isPackageForFilter(String packageName, 8340 PackageParser.ProviderIntentInfo info) { 8341 return packageName.equals(info.provider.owner.packageName); 8342 } 8343 8344 @Override 8345 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 8346 int match, int userId) { 8347 if (!sUserManager.exists(userId)) 8348 return null; 8349 final PackageParser.ProviderIntentInfo info = filter; 8350 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 8351 return null; 8352 } 8353 final PackageParser.Provider provider = info.provider; 8354 if (mSafeMode && (provider.info.applicationInfo.flags 8355 & ApplicationInfo.FLAG_SYSTEM) == 0) { 8356 return null; 8357 } 8358 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 8359 if (ps == null) { 8360 return null; 8361 } 8362 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 8363 ps.readUserState(userId), userId); 8364 if (pi == null) { 8365 return null; 8366 } 8367 final ResolveInfo res = new ResolveInfo(); 8368 res.providerInfo = pi; 8369 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 8370 res.filter = filter; 8371 } 8372 res.priority = info.getPriority(); 8373 res.preferredOrder = provider.owner.mPreferredOrder; 8374 res.match = match; 8375 res.isDefault = info.hasDefault; 8376 res.labelRes = info.labelRes; 8377 res.nonLocalizedLabel = info.nonLocalizedLabel; 8378 res.icon = info.icon; 8379 res.system = res.providerInfo.applicationInfo.isSystemApp(); 8380 return res; 8381 } 8382 8383 @Override 8384 protected void sortResults(List<ResolveInfo> results) { 8385 Collections.sort(results, mResolvePrioritySorter); 8386 } 8387 8388 @Override 8389 protected void dumpFilter(PrintWriter out, String prefix, 8390 PackageParser.ProviderIntentInfo filter) { 8391 out.print(prefix); 8392 out.print( 8393 Integer.toHexString(System.identityHashCode(filter.provider))); 8394 out.print(' '); 8395 filter.provider.printComponentShortName(out); 8396 out.print(" filter "); 8397 out.println(Integer.toHexString(System.identityHashCode(filter))); 8398 } 8399 8400 @Override 8401 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 8402 return filter.provider; 8403 } 8404 8405 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8406 PackageParser.Provider provider = (PackageParser.Provider)label; 8407 out.print(prefix); out.print( 8408 Integer.toHexString(System.identityHashCode(provider))); 8409 out.print(' '); 8410 provider.printComponentShortName(out); 8411 if (count > 1) { 8412 out.print(" ("); out.print(count); out.print(" filters)"); 8413 } 8414 out.println(); 8415 } 8416 8417 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 8418 = new ArrayMap<ComponentName, PackageParser.Provider>(); 8419 private int mFlags; 8420 }; 8421 8422 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 8423 new Comparator<ResolveInfo>() { 8424 public int compare(ResolveInfo r1, ResolveInfo r2) { 8425 int v1 = r1.priority; 8426 int v2 = r2.priority; 8427 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 8428 if (v1 != v2) { 8429 return (v1 > v2) ? -1 : 1; 8430 } 8431 v1 = r1.preferredOrder; 8432 v2 = r2.preferredOrder; 8433 if (v1 != v2) { 8434 return (v1 > v2) ? -1 : 1; 8435 } 8436 if (r1.isDefault != r2.isDefault) { 8437 return r1.isDefault ? -1 : 1; 8438 } 8439 v1 = r1.match; 8440 v2 = r2.match; 8441 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 8442 if (v1 != v2) { 8443 return (v1 > v2) ? -1 : 1; 8444 } 8445 if (r1.system != r2.system) { 8446 return r1.system ? -1 : 1; 8447 } 8448 return 0; 8449 } 8450 }; 8451 8452 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 8453 new Comparator<ProviderInfo>() { 8454 public int compare(ProviderInfo p1, ProviderInfo p2) { 8455 final int v1 = p1.initOrder; 8456 final int v2 = p2.initOrder; 8457 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 8458 } 8459 }; 8460 8461 static final void sendPackageBroadcast(String action, String pkg, 8462 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, 8463 int[] userIds) { 8464 IActivityManager am = ActivityManagerNative.getDefault(); 8465 if (am != null) { 8466 try { 8467 if (userIds == null) { 8468 userIds = am.getRunningUserIds(); 8469 } 8470 for (int id : userIds) { 8471 final Intent intent = new Intent(action, 8472 pkg != null ? Uri.fromParts("package", pkg, null) : null); 8473 if (extras != null) { 8474 intent.putExtras(extras); 8475 } 8476 if (targetPkg != null) { 8477 intent.setPackage(targetPkg); 8478 } 8479 // Modify the UID when posting to other users 8480 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 8481 if (uid > 0 && UserHandle.getUserId(uid) != id) { 8482 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 8483 intent.putExtra(Intent.EXTRA_UID, uid); 8484 } 8485 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 8486 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 8487 if (DEBUG_BROADCASTS) { 8488 RuntimeException here = new RuntimeException("here"); 8489 here.fillInStackTrace(); 8490 Slog.d(TAG, "Sending to user " + id + ": " 8491 + intent.toShortString(false, true, false, false) 8492 + " " + intent.getExtras(), here); 8493 } 8494 am.broadcastIntent(null, intent, null, finishedReceiver, 8495 0, null, null, null, android.app.AppOpsManager.OP_NONE, 8496 finishedReceiver != null, false, id); 8497 } 8498 } catch (RemoteException ex) { 8499 } 8500 } 8501 } 8502 8503 /** 8504 * Check if the external storage media is available. This is true if there 8505 * is a mounted external storage medium or if the external storage is 8506 * emulated. 8507 */ 8508 private boolean isExternalMediaAvailable() { 8509 return mMediaMounted || Environment.isExternalStorageEmulated(); 8510 } 8511 8512 @Override 8513 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 8514 // writer 8515 synchronized (mPackages) { 8516 if (!isExternalMediaAvailable()) { 8517 // If the external storage is no longer mounted at this point, 8518 // the caller may not have been able to delete all of this 8519 // packages files and can not delete any more. Bail. 8520 return null; 8521 } 8522 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 8523 if (lastPackage != null) { 8524 pkgs.remove(lastPackage); 8525 } 8526 if (pkgs.size() > 0) { 8527 return pkgs.get(0); 8528 } 8529 } 8530 return null; 8531 } 8532 8533 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 8534 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 8535 userId, andCode ? 1 : 0, packageName); 8536 if (mSystemReady) { 8537 msg.sendToTarget(); 8538 } else { 8539 if (mPostSystemReadyMessages == null) { 8540 mPostSystemReadyMessages = new ArrayList<>(); 8541 } 8542 mPostSystemReadyMessages.add(msg); 8543 } 8544 } 8545 8546 void startCleaningPackages() { 8547 // reader 8548 synchronized (mPackages) { 8549 if (!isExternalMediaAvailable()) { 8550 return; 8551 } 8552 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 8553 return; 8554 } 8555 } 8556 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 8557 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 8558 IActivityManager am = ActivityManagerNative.getDefault(); 8559 if (am != null) { 8560 try { 8561 am.startService(null, intent, null, UserHandle.USER_OWNER); 8562 } catch (RemoteException e) { 8563 } 8564 } 8565 } 8566 8567 @Override 8568 public void installPackage(String originPath, IPackageInstallObserver2 observer, 8569 int installFlags, String installerPackageName, VerificationParams verificationParams, 8570 String packageAbiOverride) { 8571 installPackageAsUser(originPath, observer, installFlags, installerPackageName, 8572 verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); 8573 } 8574 8575 @Override 8576 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 8577 int installFlags, String installerPackageName, VerificationParams verificationParams, 8578 String packageAbiOverride, int userId) { 8579 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 8580 8581 final int callingUid = Binder.getCallingUid(); 8582 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 8583 8584 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8585 try { 8586 if (observer != null) { 8587 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 8588 } 8589 } catch (RemoteException re) { 8590 } 8591 return; 8592 } 8593 8594 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 8595 installFlags |= PackageManager.INSTALL_FROM_ADB; 8596 8597 } else { 8598 // Caller holds INSTALL_PACKAGES permission, so we're less strict 8599 // about installerPackageName. 8600 8601 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 8602 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 8603 } 8604 8605 UserHandle user; 8606 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 8607 user = UserHandle.ALL; 8608 } else { 8609 user = new UserHandle(userId); 8610 } 8611 8612 verificationParams.setInstallerUid(callingUid); 8613 8614 final File originFile = new File(originPath); 8615 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 8616 8617 final Message msg = mHandler.obtainMessage(INIT_COPY); 8618 msg.obj = new InstallParams(origin, observer, installFlags, 8619 installerPackageName, null, verificationParams, user, packageAbiOverride); 8620 mHandler.sendMessage(msg); 8621 } 8622 8623 void installStage(String packageName, File stagedDir, String stagedCid, 8624 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, 8625 String installerPackageName, int installerUid, UserHandle user) { 8626 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 8627 params.referrerUri, installerUid, null); 8628 8629 final OriginInfo origin; 8630 if (stagedDir != null) { 8631 origin = OriginInfo.fromStagedFile(stagedDir); 8632 } else { 8633 origin = OriginInfo.fromStagedContainer(stagedCid); 8634 } 8635 8636 final Message msg = mHandler.obtainMessage(INIT_COPY); 8637 msg.obj = new InstallParams(origin, observer, params.installFlags, 8638 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride); 8639 mHandler.sendMessage(msg); 8640 } 8641 8642 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 8643 Bundle extras = new Bundle(1); 8644 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 8645 8646 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 8647 packageName, extras, null, null, new int[] {userId}); 8648 try { 8649 IActivityManager am = ActivityManagerNative.getDefault(); 8650 final boolean isSystem = 8651 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 8652 if (isSystem && am.isUserRunning(userId, false)) { 8653 // The just-installed/enabled app is bundled on the system, so presumed 8654 // to be able to run automatically without needing an explicit launch. 8655 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 8656 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 8657 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 8658 .setPackage(packageName); 8659 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 8660 android.app.AppOpsManager.OP_NONE, false, false, userId); 8661 } 8662 } catch (RemoteException e) { 8663 // shouldn't happen 8664 Slog.w(TAG, "Unable to bootstrap installed package", e); 8665 } 8666 } 8667 8668 @Override 8669 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 8670 int userId) { 8671 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8672 PackageSetting pkgSetting; 8673 final int uid = Binder.getCallingUid(); 8674 enforceCrossUserPermission(uid, userId, true, true, 8675 "setApplicationHiddenSetting for user " + userId); 8676 8677 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 8678 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 8679 return false; 8680 } 8681 8682 long callingId = Binder.clearCallingIdentity(); 8683 try { 8684 boolean sendAdded = false; 8685 boolean sendRemoved = false; 8686 // writer 8687 synchronized (mPackages) { 8688 pkgSetting = mSettings.mPackages.get(packageName); 8689 if (pkgSetting == null) { 8690 return false; 8691 } 8692 if (pkgSetting.getHidden(userId) != hidden) { 8693 pkgSetting.setHidden(hidden, userId); 8694 mSettings.writePackageRestrictionsLPr(userId); 8695 if (hidden) { 8696 sendRemoved = true; 8697 } else { 8698 sendAdded = true; 8699 } 8700 } 8701 } 8702 if (sendAdded) { 8703 sendPackageAddedForUser(packageName, pkgSetting, userId); 8704 return true; 8705 } 8706 if (sendRemoved) { 8707 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 8708 "hiding pkg"); 8709 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 8710 } 8711 } finally { 8712 Binder.restoreCallingIdentity(callingId); 8713 } 8714 return false; 8715 } 8716 8717 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 8718 int userId) { 8719 final PackageRemovedInfo info = new PackageRemovedInfo(); 8720 info.removedPackage = packageName; 8721 info.removedUsers = new int[] {userId}; 8722 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 8723 info.sendBroadcast(false, false, false); 8724 } 8725 8726 /** 8727 * Returns true if application is not found or there was an error. Otherwise it returns 8728 * the hidden state of the package for the given user. 8729 */ 8730 @Override 8731 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 8732 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8733 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 8734 false, "getApplicationHidden for user " + userId); 8735 PackageSetting pkgSetting; 8736 long callingId = Binder.clearCallingIdentity(); 8737 try { 8738 // writer 8739 synchronized (mPackages) { 8740 pkgSetting = mSettings.mPackages.get(packageName); 8741 if (pkgSetting == null) { 8742 return true; 8743 } 8744 return pkgSetting.getHidden(userId); 8745 } 8746 } finally { 8747 Binder.restoreCallingIdentity(callingId); 8748 } 8749 } 8750 8751 /** 8752 * @hide 8753 */ 8754 @Override 8755 public int installExistingPackageAsUser(String packageName, int userId) { 8756 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 8757 null); 8758 PackageSetting pkgSetting; 8759 final int uid = Binder.getCallingUid(); 8760 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 8761 + userId); 8762 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8763 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 8764 } 8765 8766 long callingId = Binder.clearCallingIdentity(); 8767 try { 8768 boolean sendAdded = false; 8769 Bundle extras = new Bundle(1); 8770 8771 // writer 8772 synchronized (mPackages) { 8773 pkgSetting = mSettings.mPackages.get(packageName); 8774 if (pkgSetting == null) { 8775 return PackageManager.INSTALL_FAILED_INVALID_URI; 8776 } 8777 if (!pkgSetting.getInstalled(userId)) { 8778 pkgSetting.setInstalled(true, userId); 8779 pkgSetting.setHidden(false, userId); 8780 mSettings.writePackageRestrictionsLPr(userId); 8781 sendAdded = true; 8782 } 8783 } 8784 8785 if (sendAdded) { 8786 sendPackageAddedForUser(packageName, pkgSetting, userId); 8787 } 8788 } finally { 8789 Binder.restoreCallingIdentity(callingId); 8790 } 8791 8792 return PackageManager.INSTALL_SUCCEEDED; 8793 } 8794 8795 boolean isUserRestricted(int userId, String restrictionKey) { 8796 Bundle restrictions = sUserManager.getUserRestrictions(userId); 8797 if (restrictions.getBoolean(restrictionKey, false)) { 8798 Log.w(TAG, "User is restricted: " + restrictionKey); 8799 return true; 8800 } 8801 return false; 8802 } 8803 8804 @Override 8805 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 8806 mContext.enforceCallingOrSelfPermission( 8807 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8808 "Only package verification agents can verify applications"); 8809 8810 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8811 final PackageVerificationResponse response = new PackageVerificationResponse( 8812 verificationCode, Binder.getCallingUid()); 8813 msg.arg1 = id; 8814 msg.obj = response; 8815 mHandler.sendMessage(msg); 8816 } 8817 8818 @Override 8819 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 8820 long millisecondsToDelay) { 8821 mContext.enforceCallingOrSelfPermission( 8822 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8823 "Only package verification agents can extend verification timeouts"); 8824 8825 final PackageVerificationState state = mPendingVerification.get(id); 8826 final PackageVerificationResponse response = new PackageVerificationResponse( 8827 verificationCodeAtTimeout, Binder.getCallingUid()); 8828 8829 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 8830 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 8831 } 8832 if (millisecondsToDelay < 0) { 8833 millisecondsToDelay = 0; 8834 } 8835 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 8836 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 8837 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 8838 } 8839 8840 if ((state != null) && !state.timeoutExtended()) { 8841 state.extendTimeout(); 8842 8843 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8844 msg.arg1 = id; 8845 msg.obj = response; 8846 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 8847 } 8848 } 8849 8850 private void broadcastPackageVerified(int verificationId, Uri packageUri, 8851 int verificationCode, UserHandle user) { 8852 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 8853 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 8854 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 8855 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 8856 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 8857 8858 mContext.sendBroadcastAsUser(intent, user, 8859 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 8860 } 8861 8862 private ComponentName matchComponentForVerifier(String packageName, 8863 List<ResolveInfo> receivers) { 8864 ActivityInfo targetReceiver = null; 8865 8866 final int NR = receivers.size(); 8867 for (int i = 0; i < NR; i++) { 8868 final ResolveInfo info = receivers.get(i); 8869 if (info.activityInfo == null) { 8870 continue; 8871 } 8872 8873 if (packageName.equals(info.activityInfo.packageName)) { 8874 targetReceiver = info.activityInfo; 8875 break; 8876 } 8877 } 8878 8879 if (targetReceiver == null) { 8880 return null; 8881 } 8882 8883 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 8884 } 8885 8886 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 8887 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 8888 if (pkgInfo.verifiers.length == 0) { 8889 return null; 8890 } 8891 8892 final int N = pkgInfo.verifiers.length; 8893 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 8894 for (int i = 0; i < N; i++) { 8895 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 8896 8897 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 8898 receivers); 8899 if (comp == null) { 8900 continue; 8901 } 8902 8903 final int verifierUid = getUidForVerifier(verifierInfo); 8904 if (verifierUid == -1) { 8905 continue; 8906 } 8907 8908 if (DEBUG_VERIFY) { 8909 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 8910 + " with the correct signature"); 8911 } 8912 sufficientVerifiers.add(comp); 8913 verificationState.addSufficientVerifier(verifierUid); 8914 } 8915 8916 return sufficientVerifiers; 8917 } 8918 8919 private int getUidForVerifier(VerifierInfo verifierInfo) { 8920 synchronized (mPackages) { 8921 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 8922 if (pkg == null) { 8923 return -1; 8924 } else if (pkg.mSignatures.length != 1) { 8925 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8926 + " has more than one signature; ignoring"); 8927 return -1; 8928 } 8929 8930 /* 8931 * If the public key of the package's signature does not match 8932 * our expected public key, then this is a different package and 8933 * we should skip. 8934 */ 8935 8936 final byte[] expectedPublicKey; 8937 try { 8938 final Signature verifierSig = pkg.mSignatures[0]; 8939 final PublicKey publicKey = verifierSig.getPublicKey(); 8940 expectedPublicKey = publicKey.getEncoded(); 8941 } catch (CertificateException e) { 8942 return -1; 8943 } 8944 8945 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 8946 8947 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 8948 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8949 + " does not have the expected public key; ignoring"); 8950 return -1; 8951 } 8952 8953 return pkg.applicationInfo.uid; 8954 } 8955 } 8956 8957 @Override 8958 public void finishPackageInstall(int token) { 8959 enforceSystemOrRoot("Only the system is allowed to finish installs"); 8960 8961 if (DEBUG_INSTALL) { 8962 Slog.v(TAG, "BM finishing package install for " + token); 8963 } 8964 8965 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 8966 mHandler.sendMessage(msg); 8967 } 8968 8969 /** 8970 * Get the verification agent timeout. 8971 * 8972 * @return verification timeout in milliseconds 8973 */ 8974 private long getVerificationTimeout() { 8975 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 8976 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 8977 DEFAULT_VERIFICATION_TIMEOUT); 8978 } 8979 8980 /** 8981 * Get the default verification agent response code. 8982 * 8983 * @return default verification response code 8984 */ 8985 private int getDefaultVerificationResponse() { 8986 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8987 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 8988 DEFAULT_VERIFICATION_RESPONSE); 8989 } 8990 8991 /** 8992 * Check whether or not package verification has been enabled. 8993 * 8994 * @return true if verification should be performed 8995 */ 8996 private boolean isVerificationEnabled(int userId, int installFlags) { 8997 if (!DEFAULT_VERIFY_ENABLE) { 8998 return false; 8999 } 9000 9001 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 9002 9003 // Check if installing from ADB 9004 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 9005 // Do not run verification in a test harness environment 9006 if (ActivityManager.isRunningInTestHarness()) { 9007 return false; 9008 } 9009 if (ensureVerifyAppsEnabled) { 9010 return true; 9011 } 9012 // Check if the developer does not want package verification for ADB installs 9013 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9014 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 9015 return false; 9016 } 9017 } 9018 9019 if (ensureVerifyAppsEnabled) { 9020 return true; 9021 } 9022 9023 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9024 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 9025 } 9026 9027 @Override 9028 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 9029 throws RemoteException { 9030 mContext.enforceCallingOrSelfPermission( 9031 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 9032 "Only intentfilter verification agents can verify applications"); 9033 9034 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 9035 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 9036 Binder.getCallingUid(), verificationCode, failedDomains); 9037 msg.arg1 = id; 9038 msg.obj = response; 9039 mHandler.sendMessage(msg); 9040 } 9041 9042 @Override 9043 public int getIntentVerificationStatus(String packageName, int userId) { 9044 synchronized (mPackages) { 9045 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 9046 } 9047 } 9048 9049 @Override 9050 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 9051 boolean result = false; 9052 synchronized (mPackages) { 9053 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 9054 } 9055 scheduleWritePackageRestrictionsLocked(userId); 9056 return result; 9057 } 9058 9059 @Override 9060 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 9061 synchronized (mPackages) { 9062 return mSettings.getIntentFilterVerificationsLPr(packageName); 9063 } 9064 } 9065 9066 @Override 9067 public List<IntentFilter> getAllIntentFilters(String packageName) { 9068 if (TextUtils.isEmpty(packageName)) { 9069 return Collections.<IntentFilter>emptyList(); 9070 } 9071 synchronized (mPackages) { 9072 PackageParser.Package pkg = mPackages.get(packageName); 9073 if (pkg == null || pkg.activities == null) { 9074 return Collections.<IntentFilter>emptyList(); 9075 } 9076 final int count = pkg.activities.size(); 9077 ArrayList<IntentFilter> result = new ArrayList<>(); 9078 for (int n=0; n<count; n++) { 9079 PackageParser.Activity activity = pkg.activities.get(n); 9080 if (activity.intents != null || activity.intents.size() > 0) { 9081 result.addAll(activity.intents); 9082 } 9083 } 9084 return result; 9085 } 9086 } 9087 9088 /** 9089 * Get the "allow unknown sources" setting. 9090 * 9091 * @return the current "allow unknown sources" setting 9092 */ 9093 private int getUnknownSourcesSettings() { 9094 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9095 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 9096 -1); 9097 } 9098 9099 @Override 9100 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 9101 final int uid = Binder.getCallingUid(); 9102 // writer 9103 synchronized (mPackages) { 9104 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 9105 if (targetPackageSetting == null) { 9106 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 9107 } 9108 9109 PackageSetting installerPackageSetting; 9110 if (installerPackageName != null) { 9111 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 9112 if (installerPackageSetting == null) { 9113 throw new IllegalArgumentException("Unknown installer package: " 9114 + installerPackageName); 9115 } 9116 } else { 9117 installerPackageSetting = null; 9118 } 9119 9120 Signature[] callerSignature; 9121 Object obj = mSettings.getUserIdLPr(uid); 9122 if (obj != null) { 9123 if (obj instanceof SharedUserSetting) { 9124 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 9125 } else if (obj instanceof PackageSetting) { 9126 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 9127 } else { 9128 throw new SecurityException("Bad object " + obj + " for uid " + uid); 9129 } 9130 } else { 9131 throw new SecurityException("Unknown calling uid " + uid); 9132 } 9133 9134 // Verify: can't set installerPackageName to a package that is 9135 // not signed with the same cert as the caller. 9136 if (installerPackageSetting != null) { 9137 if (compareSignatures(callerSignature, 9138 installerPackageSetting.signatures.mSignatures) 9139 != PackageManager.SIGNATURE_MATCH) { 9140 throw new SecurityException( 9141 "Caller does not have same cert as new installer package " 9142 + installerPackageName); 9143 } 9144 } 9145 9146 // Verify: if target already has an installer package, it must 9147 // be signed with the same cert as the caller. 9148 if (targetPackageSetting.installerPackageName != null) { 9149 PackageSetting setting = mSettings.mPackages.get( 9150 targetPackageSetting.installerPackageName); 9151 // If the currently set package isn't valid, then it's always 9152 // okay to change it. 9153 if (setting != null) { 9154 if (compareSignatures(callerSignature, 9155 setting.signatures.mSignatures) 9156 != PackageManager.SIGNATURE_MATCH) { 9157 throw new SecurityException( 9158 "Caller does not have same cert as old installer package " 9159 + targetPackageSetting.installerPackageName); 9160 } 9161 } 9162 } 9163 9164 // Okay! 9165 targetPackageSetting.installerPackageName = installerPackageName; 9166 scheduleWriteSettingsLocked(); 9167 } 9168 } 9169 9170 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 9171 // Queue up an async operation since the package installation may take a little while. 9172 mHandler.post(new Runnable() { 9173 public void run() { 9174 mHandler.removeCallbacks(this); 9175 // Result object to be returned 9176 PackageInstalledInfo res = new PackageInstalledInfo(); 9177 res.returnCode = currentStatus; 9178 res.uid = -1; 9179 res.pkg = null; 9180 res.removedInfo = new PackageRemovedInfo(); 9181 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 9182 args.doPreInstall(res.returnCode); 9183 synchronized (mInstallLock) { 9184 installPackageLI(args, res); 9185 } 9186 args.doPostInstall(res.returnCode, res.uid); 9187 } 9188 9189 // A restore should be performed at this point if (a) the install 9190 // succeeded, (b) the operation is not an update, and (c) the new 9191 // package has not opted out of backup participation. 9192 final boolean update = res.removedInfo.removedPackage != null; 9193 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 9194 boolean doRestore = !update 9195 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 9196 9197 // Set up the post-install work request bookkeeping. This will be used 9198 // and cleaned up by the post-install event handling regardless of whether 9199 // there's a restore pass performed. Token values are >= 1. 9200 int token; 9201 if (mNextInstallToken < 0) mNextInstallToken = 1; 9202 token = mNextInstallToken++; 9203 9204 PostInstallData data = new PostInstallData(args, res); 9205 mRunningInstalls.put(token, data); 9206 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 9207 9208 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 9209 // Pass responsibility to the Backup Manager. It will perform a 9210 // restore if appropriate, then pass responsibility back to the 9211 // Package Manager to run the post-install observer callbacks 9212 // and broadcasts. 9213 IBackupManager bm = IBackupManager.Stub.asInterface( 9214 ServiceManager.getService(Context.BACKUP_SERVICE)); 9215 if (bm != null) { 9216 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 9217 + " to BM for possible restore"); 9218 try { 9219 if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { 9220 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 9221 } else { 9222 doRestore = false; 9223 } 9224 } catch (RemoteException e) { 9225 // can't happen; the backup manager is local 9226 } catch (Exception e) { 9227 Slog.e(TAG, "Exception trying to enqueue restore", e); 9228 doRestore = false; 9229 } 9230 } else { 9231 Slog.e(TAG, "Backup Manager not found!"); 9232 doRestore = false; 9233 } 9234 } 9235 9236 if (!doRestore) { 9237 // No restore possible, or the Backup Manager was mysteriously not 9238 // available -- just fire the post-install work request directly. 9239 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 9240 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9241 mHandler.sendMessage(msg); 9242 } 9243 } 9244 }); 9245 } 9246 9247 private abstract class HandlerParams { 9248 private static final int MAX_RETRIES = 4; 9249 9250 /** 9251 * Number of times startCopy() has been attempted and had a non-fatal 9252 * error. 9253 */ 9254 private int mRetries = 0; 9255 9256 /** User handle for the user requesting the information or installation. */ 9257 private final UserHandle mUser; 9258 9259 HandlerParams(UserHandle user) { 9260 mUser = user; 9261 } 9262 9263 UserHandle getUser() { 9264 return mUser; 9265 } 9266 9267 final boolean startCopy() { 9268 boolean res; 9269 try { 9270 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 9271 9272 if (++mRetries > MAX_RETRIES) { 9273 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 9274 mHandler.sendEmptyMessage(MCS_GIVE_UP); 9275 handleServiceError(); 9276 return false; 9277 } else { 9278 handleStartCopy(); 9279 res = true; 9280 } 9281 } catch (RemoteException e) { 9282 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 9283 mHandler.sendEmptyMessage(MCS_RECONNECT); 9284 res = false; 9285 } 9286 handleReturnCode(); 9287 return res; 9288 } 9289 9290 final void serviceError() { 9291 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 9292 handleServiceError(); 9293 handleReturnCode(); 9294 } 9295 9296 abstract void handleStartCopy() throws RemoteException; 9297 abstract void handleServiceError(); 9298 abstract void handleReturnCode(); 9299 } 9300 9301 class MeasureParams extends HandlerParams { 9302 private final PackageStats mStats; 9303 private boolean mSuccess; 9304 9305 private final IPackageStatsObserver mObserver; 9306 9307 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 9308 super(new UserHandle(stats.userHandle)); 9309 mObserver = observer; 9310 mStats = stats; 9311 } 9312 9313 @Override 9314 public String toString() { 9315 return "MeasureParams{" 9316 + Integer.toHexString(System.identityHashCode(this)) 9317 + " " + mStats.packageName + "}"; 9318 } 9319 9320 @Override 9321 void handleStartCopy() throws RemoteException { 9322 synchronized (mInstallLock) { 9323 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 9324 } 9325 9326 if (mSuccess) { 9327 final boolean mounted; 9328 if (Environment.isExternalStorageEmulated()) { 9329 mounted = true; 9330 } else { 9331 final String status = Environment.getExternalStorageState(); 9332 mounted = (Environment.MEDIA_MOUNTED.equals(status) 9333 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 9334 } 9335 9336 if (mounted) { 9337 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 9338 9339 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 9340 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 9341 9342 mStats.externalDataSize = calculateDirectorySize(mContainerService, 9343 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 9344 9345 // Always subtract cache size, since it's a subdirectory 9346 mStats.externalDataSize -= mStats.externalCacheSize; 9347 9348 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 9349 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 9350 9351 mStats.externalObbSize = calculateDirectorySize(mContainerService, 9352 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 9353 } 9354 } 9355 } 9356 9357 @Override 9358 void handleReturnCode() { 9359 if (mObserver != null) { 9360 try { 9361 mObserver.onGetStatsCompleted(mStats, mSuccess); 9362 } catch (RemoteException e) { 9363 Slog.i(TAG, "Observer no longer exists."); 9364 } 9365 } 9366 } 9367 9368 @Override 9369 void handleServiceError() { 9370 Slog.e(TAG, "Could not measure application " + mStats.packageName 9371 + " external storage"); 9372 } 9373 } 9374 9375 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 9376 throws RemoteException { 9377 long result = 0; 9378 for (File path : paths) { 9379 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 9380 } 9381 return result; 9382 } 9383 9384 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 9385 for (File path : paths) { 9386 try { 9387 mcs.clearDirectory(path.getAbsolutePath()); 9388 } catch (RemoteException e) { 9389 } 9390 } 9391 } 9392 9393 static class OriginInfo { 9394 /** 9395 * Location where install is coming from, before it has been 9396 * copied/renamed into place. This could be a single monolithic APK 9397 * file, or a cluster directory. This location may be untrusted. 9398 */ 9399 final File file; 9400 final String cid; 9401 9402 /** 9403 * Flag indicating that {@link #file} or {@link #cid} has already been 9404 * staged, meaning downstream users don't need to defensively copy the 9405 * contents. 9406 */ 9407 final boolean staged; 9408 9409 /** 9410 * Flag indicating that {@link #file} or {@link #cid} is an already 9411 * installed app that is being moved. 9412 */ 9413 final boolean existing; 9414 9415 final String resolvedPath; 9416 final File resolvedFile; 9417 9418 static OriginInfo fromNothing() { 9419 return new OriginInfo(null, null, false, false); 9420 } 9421 9422 static OriginInfo fromUntrustedFile(File file) { 9423 return new OriginInfo(file, null, false, false); 9424 } 9425 9426 static OriginInfo fromExistingFile(File file) { 9427 return new OriginInfo(file, null, false, true); 9428 } 9429 9430 static OriginInfo fromStagedFile(File file) { 9431 return new OriginInfo(file, null, true, false); 9432 } 9433 9434 static OriginInfo fromStagedContainer(String cid) { 9435 return new OriginInfo(null, cid, true, false); 9436 } 9437 9438 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 9439 this.file = file; 9440 this.cid = cid; 9441 this.staged = staged; 9442 this.existing = existing; 9443 9444 if (cid != null) { 9445 resolvedPath = PackageHelper.getSdDir(cid); 9446 resolvedFile = new File(resolvedPath); 9447 } else if (file != null) { 9448 resolvedPath = file.getAbsolutePath(); 9449 resolvedFile = file; 9450 } else { 9451 resolvedPath = null; 9452 resolvedFile = null; 9453 } 9454 } 9455 } 9456 9457 class InstallParams extends HandlerParams { 9458 final OriginInfo origin; 9459 final IPackageInstallObserver2 observer; 9460 int installFlags; 9461 final String installerPackageName; 9462 final String volumeUuid; 9463 final VerificationParams verificationParams; 9464 private InstallArgs mArgs; 9465 private int mRet; 9466 final String packageAbiOverride; 9467 9468 InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, 9469 String installerPackageName, String volumeUuid, 9470 VerificationParams verificationParams, UserHandle user, String packageAbiOverride) { 9471 super(user); 9472 this.origin = origin; 9473 this.observer = observer; 9474 this.installFlags = installFlags; 9475 this.installerPackageName = installerPackageName; 9476 this.volumeUuid = volumeUuid; 9477 this.verificationParams = verificationParams; 9478 this.packageAbiOverride = packageAbiOverride; 9479 } 9480 9481 @Override 9482 public String toString() { 9483 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 9484 + " file=" + origin.file + " cid=" + origin.cid + "}"; 9485 } 9486 9487 public ManifestDigest getManifestDigest() { 9488 if (verificationParams == null) { 9489 return null; 9490 } 9491 return verificationParams.getManifestDigest(); 9492 } 9493 9494 private int installLocationPolicy(PackageInfoLite pkgLite) { 9495 String packageName = pkgLite.packageName; 9496 int installLocation = pkgLite.installLocation; 9497 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9498 // reader 9499 synchronized (mPackages) { 9500 PackageParser.Package pkg = mPackages.get(packageName); 9501 if (pkg != null) { 9502 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 9503 // Check for downgrading. 9504 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 9505 try { 9506 checkDowngrade(pkg, pkgLite); 9507 } catch (PackageManagerException e) { 9508 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 9509 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 9510 } 9511 } 9512 // Check for updated system application. 9513 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9514 if (onSd) { 9515 Slog.w(TAG, "Cannot install update to system app on sdcard"); 9516 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 9517 } 9518 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9519 } else { 9520 if (onSd) { 9521 // Install flag overrides everything. 9522 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9523 } 9524 // If current upgrade specifies particular preference 9525 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 9526 // Application explicitly specified internal. 9527 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9528 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 9529 // App explictly prefers external. Let policy decide 9530 } else { 9531 // Prefer previous location 9532 if (isExternal(pkg)) { 9533 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9534 } 9535 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9536 } 9537 } 9538 } else { 9539 // Invalid install. Return error code 9540 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 9541 } 9542 } 9543 } 9544 // All the special cases have been taken care of. 9545 // Return result based on recommended install location. 9546 if (onSd) { 9547 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9548 } 9549 return pkgLite.recommendedInstallLocation; 9550 } 9551 9552 /* 9553 * Invoke remote method to get package information and install 9554 * location values. Override install location based on default 9555 * policy if needed and then create install arguments based 9556 * on the install location. 9557 */ 9558 public void handleStartCopy() throws RemoteException { 9559 int ret = PackageManager.INSTALL_SUCCEEDED; 9560 9561 // If we're already staged, we've firmly committed to an install location 9562 if (origin.staged) { 9563 if (origin.file != null) { 9564 installFlags |= PackageManager.INSTALL_INTERNAL; 9565 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9566 } else if (origin.cid != null) { 9567 installFlags |= PackageManager.INSTALL_EXTERNAL; 9568 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9569 } else { 9570 throw new IllegalStateException("Invalid stage location"); 9571 } 9572 } 9573 9574 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9575 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 9576 9577 PackageInfoLite pkgLite = null; 9578 9579 if (onInt && onSd) { 9580 // Check if both bits are set. 9581 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 9582 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9583 } else { 9584 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 9585 packageAbiOverride); 9586 9587 /* 9588 * If we have too little free space, try to free cache 9589 * before giving up. 9590 */ 9591 if (!origin.staged && pkgLite.recommendedInstallLocation 9592 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9593 // TODO: focus freeing disk space on the target device 9594 final StorageManager storage = StorageManager.from(mContext); 9595 final long lowThreshold = storage.getStorageLowBytes( 9596 Environment.getDataDirectory()); 9597 9598 final long sizeBytes = mContainerService.calculateInstalledSize( 9599 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 9600 9601 if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) { 9602 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 9603 installFlags, packageAbiOverride); 9604 } 9605 9606 /* 9607 * The cache free must have deleted the file we 9608 * downloaded to install. 9609 * 9610 * TODO: fix the "freeCache" call to not delete 9611 * the file we care about. 9612 */ 9613 if (pkgLite.recommendedInstallLocation 9614 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9615 pkgLite.recommendedInstallLocation 9616 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 9617 } 9618 } 9619 } 9620 9621 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9622 int loc = pkgLite.recommendedInstallLocation; 9623 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 9624 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9625 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 9626 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9627 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9628 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9629 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 9630 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 9631 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9632 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 9633 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 9634 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 9635 } else { 9636 // Override with defaults if needed. 9637 loc = installLocationPolicy(pkgLite); 9638 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 9639 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 9640 } else if (!onSd && !onInt) { 9641 // Override install location with flags 9642 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 9643 // Set the flag to install on external media. 9644 installFlags |= PackageManager.INSTALL_EXTERNAL; 9645 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9646 } else { 9647 // Make sure the flag for installing on external 9648 // media is unset 9649 installFlags |= PackageManager.INSTALL_INTERNAL; 9650 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9651 } 9652 } 9653 } 9654 } 9655 9656 final InstallArgs args = createInstallArgs(this); 9657 mArgs = args; 9658 9659 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9660 /* 9661 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 9662 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 9663 */ 9664 int userIdentifier = getUser().getIdentifier(); 9665 if (userIdentifier == UserHandle.USER_ALL 9666 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) { 9667 userIdentifier = UserHandle.USER_OWNER; 9668 } 9669 9670 /* 9671 * Determine if we have any installed package verifiers. If we 9672 * do, then we'll defer to them to verify the packages. 9673 */ 9674 final int requiredUid = mRequiredVerifierPackage == null ? -1 9675 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 9676 if (!origin.existing && requiredUid != -1 9677 && isVerificationEnabled(userIdentifier, installFlags)) { 9678 final Intent verification = new Intent( 9679 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 9680 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9681 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 9682 PACKAGE_MIME_TYPE); 9683 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 9684 9685 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 9686 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 9687 0 /* TODO: Which userId? */); 9688 9689 if (DEBUG_VERIFY) { 9690 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 9691 + verification.toString() + " with " + pkgLite.verifiers.length 9692 + " optional verifiers"); 9693 } 9694 9695 final int verificationId = mPendingVerificationToken++; 9696 9697 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 9698 9699 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 9700 installerPackageName); 9701 9702 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 9703 installFlags); 9704 9705 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 9706 pkgLite.packageName); 9707 9708 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 9709 pkgLite.versionCode); 9710 9711 if (verificationParams != null) { 9712 if (verificationParams.getVerificationURI() != null) { 9713 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 9714 verificationParams.getVerificationURI()); 9715 } 9716 if (verificationParams.getOriginatingURI() != null) { 9717 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 9718 verificationParams.getOriginatingURI()); 9719 } 9720 if (verificationParams.getReferrer() != null) { 9721 verification.putExtra(Intent.EXTRA_REFERRER, 9722 verificationParams.getReferrer()); 9723 } 9724 if (verificationParams.getOriginatingUid() >= 0) { 9725 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 9726 verificationParams.getOriginatingUid()); 9727 } 9728 if (verificationParams.getInstallerUid() >= 0) { 9729 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 9730 verificationParams.getInstallerUid()); 9731 } 9732 } 9733 9734 final PackageVerificationState verificationState = new PackageVerificationState( 9735 requiredUid, args); 9736 9737 mPendingVerification.append(verificationId, verificationState); 9738 9739 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 9740 receivers, verificationState); 9741 9742 /* 9743 * If any sufficient verifiers were listed in the package 9744 * manifest, attempt to ask them. 9745 */ 9746 if (sufficientVerifiers != null) { 9747 final int N = sufficientVerifiers.size(); 9748 if (N == 0) { 9749 Slog.i(TAG, "Additional verifiers required, but none installed."); 9750 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 9751 } else { 9752 for (int i = 0; i < N; i++) { 9753 final ComponentName verifierComponent = sufficientVerifiers.get(i); 9754 9755 final Intent sufficientIntent = new Intent(verification); 9756 sufficientIntent.setComponent(verifierComponent); 9757 9758 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 9759 } 9760 } 9761 } 9762 9763 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 9764 mRequiredVerifierPackage, receivers); 9765 if (ret == PackageManager.INSTALL_SUCCEEDED 9766 && mRequiredVerifierPackage != null) { 9767 /* 9768 * Send the intent to the required verification agent, 9769 * but only start the verification timeout after the 9770 * target BroadcastReceivers have run. 9771 */ 9772 verification.setComponent(requiredVerifierComponent); 9773 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 9774 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9775 new BroadcastReceiver() { 9776 @Override 9777 public void onReceive(Context context, Intent intent) { 9778 final Message msg = mHandler 9779 .obtainMessage(CHECK_PENDING_VERIFICATION); 9780 msg.arg1 = verificationId; 9781 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 9782 } 9783 }, null, 0, null, null); 9784 9785 /* 9786 * We don't want the copy to proceed until verification 9787 * succeeds, so null out this field. 9788 */ 9789 mArgs = null; 9790 } 9791 } else { 9792 /* 9793 * No package verification is enabled, so immediately start 9794 * the remote call to initiate copy using temporary file. 9795 */ 9796 ret = args.copyApk(mContainerService, true); 9797 } 9798 } 9799 9800 mRet = ret; 9801 } 9802 9803 @Override 9804 void handleReturnCode() { 9805 // If mArgs is null, then MCS couldn't be reached. When it 9806 // reconnects, it will try again to install. At that point, this 9807 // will succeed. 9808 if (mArgs != null) { 9809 processPendingInstall(mArgs, mRet); 9810 } 9811 } 9812 9813 @Override 9814 void handleServiceError() { 9815 mArgs = createInstallArgs(this); 9816 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 9817 } 9818 9819 public boolean isForwardLocked() { 9820 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9821 } 9822 } 9823 9824 /** 9825 * Used during creation of InstallArgs 9826 * 9827 * @param installFlags package installation flags 9828 * @return true if should be installed on external storage 9829 */ 9830 private static boolean installOnExternalAsec(int installFlags) { 9831 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 9832 return false; 9833 } 9834 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 9835 return true; 9836 } 9837 return false; 9838 } 9839 9840 /** 9841 * Used during creation of InstallArgs 9842 * 9843 * @param installFlags package installation flags 9844 * @return true if should be installed as forward locked 9845 */ 9846 private static boolean installForwardLocked(int installFlags) { 9847 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9848 } 9849 9850 private InstallArgs createInstallArgs(InstallParams params) { 9851 if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 9852 return new AsecInstallArgs(params); 9853 } else { 9854 return new FileInstallArgs(params); 9855 } 9856 } 9857 9858 /** 9859 * Create args that describe an existing installed package. Typically used 9860 * when cleaning up old installs, or used as a move source. 9861 */ 9862 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 9863 String resourcePath, String nativeLibraryRoot, String[] instructionSets) { 9864 final boolean isInAsec; 9865 if (installOnExternalAsec(installFlags)) { 9866 /* Apps on SD card are always in ASEC containers. */ 9867 isInAsec = true; 9868 } else if (installForwardLocked(installFlags) 9869 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 9870 /* 9871 * Forward-locked apps are only in ASEC containers if they're the 9872 * new style 9873 */ 9874 isInAsec = true; 9875 } else { 9876 isInAsec = false; 9877 } 9878 9879 if (isInAsec) { 9880 return new AsecInstallArgs(codePath, instructionSets, 9881 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 9882 } else { 9883 return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot, 9884 instructionSets); 9885 } 9886 } 9887 9888 static abstract class InstallArgs { 9889 /** @see InstallParams#origin */ 9890 final OriginInfo origin; 9891 9892 final IPackageInstallObserver2 observer; 9893 // Always refers to PackageManager flags only 9894 final int installFlags; 9895 final String installerPackageName; 9896 final String volumeUuid; 9897 final ManifestDigest manifestDigest; 9898 final UserHandle user; 9899 final String abiOverride; 9900 9901 // The list of instruction sets supported by this app. This is currently 9902 // only used during the rmdex() phase to clean up resources. We can get rid of this 9903 // if we move dex files under the common app path. 9904 /* nullable */ String[] instructionSets; 9905 9906 InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, 9907 String installerPackageName, String volumeUuid, ManifestDigest manifestDigest, 9908 UserHandle user, String[] instructionSets, String abiOverride) { 9909 this.origin = origin; 9910 this.installFlags = installFlags; 9911 this.observer = observer; 9912 this.installerPackageName = installerPackageName; 9913 this.volumeUuid = volumeUuid; 9914 this.manifestDigest = manifestDigest; 9915 this.user = user; 9916 this.instructionSets = instructionSets; 9917 this.abiOverride = abiOverride; 9918 } 9919 9920 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 9921 abstract int doPreInstall(int status); 9922 9923 /** 9924 * Rename package into final resting place. All paths on the given 9925 * scanned package should be updated to reflect the rename. 9926 */ 9927 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 9928 abstract int doPostInstall(int status, int uid); 9929 9930 /** @see PackageSettingBase#codePathString */ 9931 abstract String getCodePath(); 9932 /** @see PackageSettingBase#resourcePathString */ 9933 abstract String getResourcePath(); 9934 abstract String getLegacyNativeLibraryPath(); 9935 9936 // Need installer lock especially for dex file removal. 9937 abstract void cleanUpResourcesLI(); 9938 abstract boolean doPostDeleteLI(boolean delete); 9939 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 9940 9941 /** 9942 * Called before the source arguments are copied. This is used mostly 9943 * for MoveParams when it needs to read the source file to put it in the 9944 * destination. 9945 */ 9946 int doPreCopy() { 9947 return PackageManager.INSTALL_SUCCEEDED; 9948 } 9949 9950 /** 9951 * Called after the source arguments are copied. This is used mostly for 9952 * MoveParams when it needs to read the source file to put it in the 9953 * destination. 9954 * 9955 * @return 9956 */ 9957 int doPostCopy(int uid) { 9958 return PackageManager.INSTALL_SUCCEEDED; 9959 } 9960 9961 protected boolean isFwdLocked() { 9962 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9963 } 9964 9965 protected boolean isExternalAsec() { 9966 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9967 } 9968 9969 UserHandle getUser() { 9970 return user; 9971 } 9972 } 9973 9974 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 9975 if (!allCodePaths.isEmpty()) { 9976 if (instructionSets == null) { 9977 throw new IllegalStateException("instructionSet == null"); 9978 } 9979 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 9980 for (String codePath : allCodePaths) { 9981 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 9982 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 9983 if (retCode < 0) { 9984 Slog.w(TAG, "Couldn't remove dex file for package: " 9985 + " at location " + codePath + ", retcode=" + retCode); 9986 // we don't consider this to be a failure of the core package deletion 9987 } 9988 } 9989 } 9990 } 9991 } 9992 9993 /** 9994 * Logic to handle installation of non-ASEC applications, including copying 9995 * and renaming logic. 9996 */ 9997 class FileInstallArgs extends InstallArgs { 9998 private File codeFile; 9999 private File resourceFile; 10000 private File legacyNativeLibraryPath; 10001 10002 // Example topology: 10003 // /data/app/com.example/base.apk 10004 // /data/app/com.example/split_foo.apk 10005 // /data/app/com.example/lib/arm/libfoo.so 10006 // /data/app/com.example/lib/arm64/libfoo.so 10007 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 10008 10009 /** New install */ 10010 FileInstallArgs(InstallParams params) { 10011 super(params.origin, params.observer, params.installFlags, 10012 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10013 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10014 if (isFwdLocked()) { 10015 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 10016 } 10017 } 10018 10019 /** Existing install */ 10020 FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath, 10021 String[] instructionSets) { 10022 super(OriginInfo.fromNothing(), null, 0, null, null, null, null, instructionSets, null); 10023 this.codeFile = (codePath != null) ? new File(codePath) : null; 10024 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 10025 this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ? 10026 new File(legacyNativeLibraryPath) : null; 10027 } 10028 10029 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 10030 final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(), 10031 isFwdLocked(), abiOverride); 10032 10033 final StorageManager storage = StorageManager.from(mContext); 10034 return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory())); 10035 } 10036 10037 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10038 if (origin.staged) { 10039 Slog.d(TAG, origin.file + " already staged; skipping copy"); 10040 codeFile = origin.file; 10041 resourceFile = origin.file; 10042 return PackageManager.INSTALL_SUCCEEDED; 10043 } 10044 10045 try { 10046 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid); 10047 codeFile = tempDir; 10048 resourceFile = tempDir; 10049 } catch (IOException e) { 10050 Slog.w(TAG, "Failed to create copy file: " + e); 10051 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10052 } 10053 10054 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 10055 @Override 10056 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 10057 if (!FileUtils.isValidExtFilename(name)) { 10058 throw new IllegalArgumentException("Invalid filename: " + name); 10059 } 10060 try { 10061 final File file = new File(codeFile, name); 10062 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 10063 O_RDWR | O_CREAT, 0644); 10064 Os.chmod(file.getAbsolutePath(), 0644); 10065 return new ParcelFileDescriptor(fd); 10066 } catch (ErrnoException e) { 10067 throw new RemoteException("Failed to open: " + e.getMessage()); 10068 } 10069 } 10070 }; 10071 10072 int ret = PackageManager.INSTALL_SUCCEEDED; 10073 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 10074 if (ret != PackageManager.INSTALL_SUCCEEDED) { 10075 Slog.e(TAG, "Failed to copy package"); 10076 return ret; 10077 } 10078 10079 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 10080 NativeLibraryHelper.Handle handle = null; 10081 try { 10082 handle = NativeLibraryHelper.Handle.create(codeFile); 10083 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 10084 abiOverride); 10085 } catch (IOException e) { 10086 Slog.e(TAG, "Copying native libraries failed", e); 10087 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10088 } finally { 10089 IoUtils.closeQuietly(handle); 10090 } 10091 10092 return ret; 10093 } 10094 10095 int doPreInstall(int status) { 10096 if (status != PackageManager.INSTALL_SUCCEEDED) { 10097 cleanUp(); 10098 } 10099 return status; 10100 } 10101 10102 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10103 if (status != PackageManager.INSTALL_SUCCEEDED) { 10104 cleanUp(); 10105 return false; 10106 } else { 10107 final File targetDir = codeFile.getParentFile(); 10108 final File beforeCodeFile = codeFile; 10109 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 10110 10111 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 10112 try { 10113 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 10114 } catch (ErrnoException e) { 10115 Slog.d(TAG, "Failed to rename", e); 10116 return false; 10117 } 10118 10119 if (!SELinux.restoreconRecursive(afterCodeFile)) { 10120 Slog.d(TAG, "Failed to restorecon"); 10121 return false; 10122 } 10123 10124 // Reflect the rename internally 10125 codeFile = afterCodeFile; 10126 resourceFile = afterCodeFile; 10127 10128 // Reflect the rename in scanned details 10129 pkg.codePath = afterCodeFile.getAbsolutePath(); 10130 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10131 pkg.baseCodePath); 10132 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10133 pkg.splitCodePaths); 10134 10135 // Reflect the rename in app info 10136 pkg.applicationInfo.setCodePath(pkg.codePath); 10137 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10138 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10139 pkg.applicationInfo.setResourcePath(pkg.codePath); 10140 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10141 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10142 10143 return true; 10144 } 10145 } 10146 10147 int doPostInstall(int status, int uid) { 10148 if (status != PackageManager.INSTALL_SUCCEEDED) { 10149 cleanUp(); 10150 } 10151 return status; 10152 } 10153 10154 @Override 10155 String getCodePath() { 10156 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 10157 } 10158 10159 @Override 10160 String getResourcePath() { 10161 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 10162 } 10163 10164 @Override 10165 String getLegacyNativeLibraryPath() { 10166 return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null; 10167 } 10168 10169 private boolean cleanUp() { 10170 if (codeFile == null || !codeFile.exists()) { 10171 return false; 10172 } 10173 10174 if (codeFile.isDirectory()) { 10175 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 10176 } else { 10177 codeFile.delete(); 10178 } 10179 10180 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 10181 resourceFile.delete(); 10182 } 10183 10184 if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) { 10185 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) { 10186 Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath); 10187 } 10188 legacyNativeLibraryPath.delete(); 10189 } 10190 10191 return true; 10192 } 10193 10194 void cleanUpResourcesLI() { 10195 // Try enumerating all code paths before deleting 10196 List<String> allCodePaths = Collections.EMPTY_LIST; 10197 if (codeFile != null && codeFile.exists()) { 10198 try { 10199 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10200 allCodePaths = pkg.getAllCodePaths(); 10201 } catch (PackageParserException e) { 10202 // Ignored; we tried our best 10203 } 10204 } 10205 10206 cleanUp(); 10207 removeDexFiles(allCodePaths, instructionSets); 10208 } 10209 10210 boolean doPostDeleteLI(boolean delete) { 10211 // XXX err, shouldn't we respect the delete flag? 10212 cleanUpResourcesLI(); 10213 return true; 10214 } 10215 } 10216 10217 private boolean isAsecExternal(String cid) { 10218 final String asecPath = PackageHelper.getSdFilesystem(cid); 10219 return !asecPath.startsWith(mAsecInternalPath); 10220 } 10221 10222 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 10223 PackageManagerException { 10224 if (copyRet < 0) { 10225 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 10226 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 10227 throw new PackageManagerException(copyRet, message); 10228 } 10229 } 10230 } 10231 10232 /** 10233 * Extract the MountService "container ID" from the full code path of an 10234 * .apk. 10235 */ 10236 static String cidFromCodePath(String fullCodePath) { 10237 int eidx = fullCodePath.lastIndexOf("/"); 10238 String subStr1 = fullCodePath.substring(0, eidx); 10239 int sidx = subStr1.lastIndexOf("/"); 10240 return subStr1.substring(sidx+1, eidx); 10241 } 10242 10243 /** 10244 * Logic to handle installation of ASEC applications, including copying and 10245 * renaming logic. 10246 */ 10247 class AsecInstallArgs extends InstallArgs { 10248 static final String RES_FILE_NAME = "pkg.apk"; 10249 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 10250 10251 String cid; 10252 String packagePath; 10253 String resourcePath; 10254 String legacyNativeLibraryDir; 10255 10256 /** New install */ 10257 AsecInstallArgs(InstallParams params) { 10258 super(params.origin, params.observer, params.installFlags, 10259 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10260 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10261 } 10262 10263 /** Existing install */ 10264 AsecInstallArgs(String fullCodePath, String[] instructionSets, 10265 boolean isExternal, boolean isForwardLocked) { 10266 super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0) 10267 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10268 instructionSets, null); 10269 // Hackily pretend we're still looking at a full code path 10270 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 10271 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 10272 } 10273 10274 // Extract cid from fullCodePath 10275 int eidx = fullCodePath.lastIndexOf("/"); 10276 String subStr1 = fullCodePath.substring(0, eidx); 10277 int sidx = subStr1.lastIndexOf("/"); 10278 cid = subStr1.substring(sidx+1, eidx); 10279 setMountPath(subStr1); 10280 } 10281 10282 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 10283 super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 10284 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10285 instructionSets, null); 10286 this.cid = cid; 10287 setMountPath(PackageHelper.getSdDir(cid)); 10288 } 10289 10290 void createCopyFile() { 10291 cid = mInstallerService.allocateExternalStageCidLegacy(); 10292 } 10293 10294 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 10295 final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(), 10296 abiOverride); 10297 10298 final File target; 10299 if (isExternalAsec()) { 10300 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory(); 10301 } else { 10302 target = Environment.getDataDirectory(); 10303 } 10304 10305 final StorageManager storage = StorageManager.from(mContext); 10306 return (sizeBytes <= storage.getStorageBytesUntilLow(target)); 10307 } 10308 10309 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10310 if (origin.staged) { 10311 Slog.d(TAG, origin.cid + " already staged; skipping copy"); 10312 cid = origin.cid; 10313 setMountPath(PackageHelper.getSdDir(cid)); 10314 return PackageManager.INSTALL_SUCCEEDED; 10315 } 10316 10317 if (temp) { 10318 createCopyFile(); 10319 } else { 10320 /* 10321 * Pre-emptively destroy the container since it's destroyed if 10322 * copying fails due to it existing anyway. 10323 */ 10324 PackageHelper.destroySdDir(cid); 10325 } 10326 10327 final String newMountPath = imcs.copyPackageToContainer( 10328 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 10329 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 10330 10331 if (newMountPath != null) { 10332 setMountPath(newMountPath); 10333 return PackageManager.INSTALL_SUCCEEDED; 10334 } else { 10335 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10336 } 10337 } 10338 10339 @Override 10340 String getCodePath() { 10341 return packagePath; 10342 } 10343 10344 @Override 10345 String getResourcePath() { 10346 return resourcePath; 10347 } 10348 10349 @Override 10350 String getLegacyNativeLibraryPath() { 10351 return legacyNativeLibraryDir; 10352 } 10353 10354 int doPreInstall(int status) { 10355 if (status != PackageManager.INSTALL_SUCCEEDED) { 10356 // Destroy container 10357 PackageHelper.destroySdDir(cid); 10358 } else { 10359 boolean mounted = PackageHelper.isContainerMounted(cid); 10360 if (!mounted) { 10361 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 10362 Process.SYSTEM_UID); 10363 if (newMountPath != null) { 10364 setMountPath(newMountPath); 10365 } else { 10366 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10367 } 10368 } 10369 } 10370 return status; 10371 } 10372 10373 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10374 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 10375 String newMountPath = null; 10376 if (PackageHelper.isContainerMounted(cid)) { 10377 // Unmount the container 10378 if (!PackageHelper.unMountSdDir(cid)) { 10379 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 10380 return false; 10381 } 10382 } 10383 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10384 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 10385 " which might be stale. Will try to clean up."); 10386 // Clean up the stale container and proceed to recreate. 10387 if (!PackageHelper.destroySdDir(newCacheId)) { 10388 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 10389 return false; 10390 } 10391 // Successfully cleaned up stale container. Try to rename again. 10392 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10393 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 10394 + " inspite of cleaning it up."); 10395 return false; 10396 } 10397 } 10398 if (!PackageHelper.isContainerMounted(newCacheId)) { 10399 Slog.w(TAG, "Mounting container " + newCacheId); 10400 newMountPath = PackageHelper.mountSdDir(newCacheId, 10401 getEncryptKey(), Process.SYSTEM_UID); 10402 } else { 10403 newMountPath = PackageHelper.getSdDir(newCacheId); 10404 } 10405 if (newMountPath == null) { 10406 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 10407 return false; 10408 } 10409 Log.i(TAG, "Succesfully renamed " + cid + 10410 " to " + newCacheId + 10411 " at new path: " + newMountPath); 10412 cid = newCacheId; 10413 10414 final File beforeCodeFile = new File(packagePath); 10415 setMountPath(newMountPath); 10416 final File afterCodeFile = new File(packagePath); 10417 10418 // Reflect the rename in scanned details 10419 pkg.codePath = afterCodeFile.getAbsolutePath(); 10420 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10421 pkg.baseCodePath); 10422 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10423 pkg.splitCodePaths); 10424 10425 // Reflect the rename in app info 10426 pkg.applicationInfo.setCodePath(pkg.codePath); 10427 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10428 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10429 pkg.applicationInfo.setResourcePath(pkg.codePath); 10430 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10431 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10432 10433 return true; 10434 } 10435 10436 private void setMountPath(String mountPath) { 10437 final File mountFile = new File(mountPath); 10438 10439 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 10440 if (monolithicFile.exists()) { 10441 packagePath = monolithicFile.getAbsolutePath(); 10442 if (isFwdLocked()) { 10443 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 10444 } else { 10445 resourcePath = packagePath; 10446 } 10447 } else { 10448 packagePath = mountFile.getAbsolutePath(); 10449 resourcePath = packagePath; 10450 } 10451 10452 legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath(); 10453 } 10454 10455 int doPostInstall(int status, int uid) { 10456 if (status != PackageManager.INSTALL_SUCCEEDED) { 10457 cleanUp(); 10458 } else { 10459 final int groupOwner; 10460 final String protectedFile; 10461 if (isFwdLocked()) { 10462 groupOwner = UserHandle.getSharedAppGid(uid); 10463 protectedFile = RES_FILE_NAME; 10464 } else { 10465 groupOwner = -1; 10466 protectedFile = null; 10467 } 10468 10469 if (uid < Process.FIRST_APPLICATION_UID 10470 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 10471 Slog.e(TAG, "Failed to finalize " + cid); 10472 PackageHelper.destroySdDir(cid); 10473 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10474 } 10475 10476 boolean mounted = PackageHelper.isContainerMounted(cid); 10477 if (!mounted) { 10478 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 10479 } 10480 } 10481 return status; 10482 } 10483 10484 private void cleanUp() { 10485 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 10486 10487 // Destroy secure container 10488 PackageHelper.destroySdDir(cid); 10489 } 10490 10491 private List<String> getAllCodePaths() { 10492 final File codeFile = new File(getCodePath()); 10493 if (codeFile != null && codeFile.exists()) { 10494 try { 10495 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10496 return pkg.getAllCodePaths(); 10497 } catch (PackageParserException e) { 10498 // Ignored; we tried our best 10499 } 10500 } 10501 return Collections.EMPTY_LIST; 10502 } 10503 10504 void cleanUpResourcesLI() { 10505 // Enumerate all code paths before deleting 10506 cleanUpResourcesLI(getAllCodePaths()); 10507 } 10508 10509 private void cleanUpResourcesLI(List<String> allCodePaths) { 10510 cleanUp(); 10511 removeDexFiles(allCodePaths, instructionSets); 10512 } 10513 10514 10515 10516 String getPackageName() { 10517 return getAsecPackageName(cid); 10518 } 10519 10520 boolean doPostDeleteLI(boolean delete) { 10521 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 10522 final List<String> allCodePaths = getAllCodePaths(); 10523 boolean mounted = PackageHelper.isContainerMounted(cid); 10524 if (mounted) { 10525 // Unmount first 10526 if (PackageHelper.unMountSdDir(cid)) { 10527 mounted = false; 10528 } 10529 } 10530 if (!mounted && delete) { 10531 cleanUpResourcesLI(allCodePaths); 10532 } 10533 return !mounted; 10534 } 10535 10536 @Override 10537 int doPreCopy() { 10538 if (isFwdLocked()) { 10539 if (!PackageHelper.fixSdPermissions(cid, 10540 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 10541 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10542 } 10543 } 10544 10545 return PackageManager.INSTALL_SUCCEEDED; 10546 } 10547 10548 @Override 10549 int doPostCopy(int uid) { 10550 if (isFwdLocked()) { 10551 if (uid < Process.FIRST_APPLICATION_UID 10552 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 10553 RES_FILE_NAME)) { 10554 Slog.e(TAG, "Failed to finalize " + cid); 10555 PackageHelper.destroySdDir(cid); 10556 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10557 } 10558 } 10559 10560 return PackageManager.INSTALL_SUCCEEDED; 10561 } 10562 } 10563 10564 static String getAsecPackageName(String packageCid) { 10565 int idx = packageCid.lastIndexOf("-"); 10566 if (idx == -1) { 10567 return packageCid; 10568 } 10569 return packageCid.substring(0, idx); 10570 } 10571 10572 // Utility method used to create code paths based on package name and available index. 10573 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 10574 String idxStr = ""; 10575 int idx = 1; 10576 // Fall back to default value of idx=1 if prefix is not 10577 // part of oldCodePath 10578 if (oldCodePath != null) { 10579 String subStr = oldCodePath; 10580 // Drop the suffix right away 10581 if (suffix != null && subStr.endsWith(suffix)) { 10582 subStr = subStr.substring(0, subStr.length() - suffix.length()); 10583 } 10584 // If oldCodePath already contains prefix find out the 10585 // ending index to either increment or decrement. 10586 int sidx = subStr.lastIndexOf(prefix); 10587 if (sidx != -1) { 10588 subStr = subStr.substring(sidx + prefix.length()); 10589 if (subStr != null) { 10590 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 10591 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 10592 } 10593 try { 10594 idx = Integer.parseInt(subStr); 10595 if (idx <= 1) { 10596 idx++; 10597 } else { 10598 idx--; 10599 } 10600 } catch(NumberFormatException e) { 10601 } 10602 } 10603 } 10604 } 10605 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 10606 return prefix + idxStr; 10607 } 10608 10609 private File getNextCodePath(File targetDir, String packageName) { 10610 int suffix = 1; 10611 File result; 10612 do { 10613 result = new File(targetDir, packageName + "-" + suffix); 10614 suffix++; 10615 } while (result.exists()); 10616 return result; 10617 } 10618 10619 // Utility method that returns the relative package path with respect 10620 // to the installation directory. Like say for /data/data/com.test-1.apk 10621 // string com.test-1 is returned. 10622 static String deriveCodePathName(String codePath) { 10623 if (codePath == null) { 10624 return null; 10625 } 10626 final File codeFile = new File(codePath); 10627 final String name = codeFile.getName(); 10628 if (codeFile.isDirectory()) { 10629 return name; 10630 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 10631 final int lastDot = name.lastIndexOf('.'); 10632 return name.substring(0, lastDot); 10633 } else { 10634 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 10635 return null; 10636 } 10637 } 10638 10639 class PackageInstalledInfo { 10640 String name; 10641 int uid; 10642 // The set of users that originally had this package installed. 10643 int[] origUsers; 10644 // The set of users that now have this package installed. 10645 int[] newUsers; 10646 PackageParser.Package pkg; 10647 int returnCode; 10648 String returnMsg; 10649 PackageRemovedInfo removedInfo; 10650 10651 public void setError(int code, String msg) { 10652 returnCode = code; 10653 returnMsg = msg; 10654 Slog.w(TAG, msg); 10655 } 10656 10657 public void setError(String msg, PackageParserException e) { 10658 returnCode = e.error; 10659 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10660 Slog.w(TAG, msg, e); 10661 } 10662 10663 public void setError(String msg, PackageManagerException e) { 10664 returnCode = e.error; 10665 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10666 Slog.w(TAG, msg, e); 10667 } 10668 10669 // In some error cases we want to convey more info back to the observer 10670 String origPackage; 10671 String origPermission; 10672 } 10673 10674 /* 10675 * Install a non-existing package. 10676 */ 10677 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 10678 UserHandle user, String installerPackageName, String volumeUuid, 10679 PackageInstalledInfo res) { 10680 // Remember this for later, in case we need to rollback this install 10681 String pkgName = pkg.packageName; 10682 10683 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 10684 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists(); 10685 synchronized(mPackages) { 10686 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 10687 // A package with the same name is already installed, though 10688 // it has been renamed to an older name. The package we 10689 // are trying to install should be installed as an update to 10690 // the existing one, but that has not been requested, so bail. 10691 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10692 + " without first uninstalling package running as " 10693 + mSettings.mRenamedPackages.get(pkgName)); 10694 return; 10695 } 10696 if (mPackages.containsKey(pkgName)) { 10697 // Don't allow installation over an existing package with the same name. 10698 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10699 + " without first uninstalling."); 10700 return; 10701 } 10702 } 10703 10704 try { 10705 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 10706 System.currentTimeMillis(), user); 10707 10708 updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user); 10709 // delete the partially installed application. the data directory will have to be 10710 // restored if it was already existing 10711 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10712 // remove package from internal structures. Note that we want deletePackageX to 10713 // delete the package data and cache directories that it created in 10714 // scanPackageLocked, unless those directories existed before we even tried to 10715 // install. 10716 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 10717 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 10718 res.removedInfo, true); 10719 } 10720 10721 } catch (PackageManagerException e) { 10722 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10723 } 10724 } 10725 10726 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 10727 // Upgrade keysets are being used. Determine if new package has a superset of the 10728 // required keys. 10729 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 10730 KeySetManagerService ksms = mSettings.mKeySetManagerService; 10731 for (int i = 0; i < upgradeKeySets.length; i++) { 10732 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 10733 if (newPkg.mSigningKeys.containsAll(upgradeSet)) { 10734 return true; 10735 } 10736 } 10737 return false; 10738 } 10739 10740 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 10741 UserHandle user, String installerPackageName, String volumeUuid, 10742 PackageInstalledInfo res) { 10743 PackageParser.Package oldPackage; 10744 String pkgName = pkg.packageName; 10745 int[] allUsers; 10746 boolean[] perUserInstalled; 10747 10748 // First find the old package info and check signatures 10749 synchronized(mPackages) { 10750 oldPackage = mPackages.get(pkgName); 10751 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 10752 PackageSetting ps = mSettings.mPackages.get(pkgName); 10753 if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 10754 // default to original signature matching 10755 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 10756 != PackageManager.SIGNATURE_MATCH) { 10757 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10758 "New package has a different signature: " + pkgName); 10759 return; 10760 } 10761 } else { 10762 if(!checkUpgradeKeySetLP(ps, pkg)) { 10763 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10764 "New package not signed by keys specified by upgrade-keysets: " 10765 + pkgName); 10766 return; 10767 } 10768 } 10769 10770 // In case of rollback, remember per-user/profile install state 10771 allUsers = sUserManager.getUserIds(); 10772 perUserInstalled = new boolean[allUsers.length]; 10773 for (int i = 0; i < allUsers.length; i++) { 10774 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 10775 } 10776 } 10777 10778 boolean sysPkg = (isSystemApp(oldPackage)); 10779 if (sysPkg) { 10780 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10781 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 10782 } else { 10783 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10784 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 10785 } 10786 } 10787 10788 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 10789 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 10790 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 10791 String volumeUuid, PackageInstalledInfo res) { 10792 String pkgName = deletedPackage.packageName; 10793 boolean deletedPkg = true; 10794 boolean updatedSettings = false; 10795 10796 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 10797 + deletedPackage); 10798 long origUpdateTime; 10799 if (pkg.mExtras != null) { 10800 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 10801 } else { 10802 origUpdateTime = 0; 10803 } 10804 10805 // First delete the existing package while retaining the data directory 10806 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 10807 res.removedInfo, true)) { 10808 // If the existing package wasn't successfully deleted 10809 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 10810 deletedPkg = false; 10811 } else { 10812 // Successfully deleted the old package; proceed with replace. 10813 10814 // If deleted package lived in a container, give users a chance to 10815 // relinquish resources before killing. 10816 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 10817 if (DEBUG_INSTALL) { 10818 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 10819 } 10820 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 10821 final ArrayList<String> pkgList = new ArrayList<String>(1); 10822 pkgList.add(deletedPackage.applicationInfo.packageName); 10823 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 10824 } 10825 10826 deleteCodeCacheDirsLI(pkgName); 10827 try { 10828 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, 10829 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 10830 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 10831 perUserInstalled, res, user); 10832 updatedSettings = true; 10833 } catch (PackageManagerException e) { 10834 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10835 } 10836 } 10837 10838 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10839 // remove package from internal structures. Note that we want deletePackageX to 10840 // delete the package data and cache directories that it created in 10841 // scanPackageLocked, unless those directories existed before we even tried to 10842 // install. 10843 if(updatedSettings) { 10844 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 10845 deletePackageLI( 10846 pkgName, null, true, allUsers, perUserInstalled, 10847 PackageManager.DELETE_KEEP_DATA, 10848 res.removedInfo, true); 10849 } 10850 // Since we failed to install the new package we need to restore the old 10851 // package that we deleted. 10852 if (deletedPkg) { 10853 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 10854 File restoreFile = new File(deletedPackage.codePath); 10855 // Parse old package 10856 boolean oldExternal = isExternal(deletedPackage); 10857 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 10858 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 10859 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 10860 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 10861 try { 10862 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null); 10863 } catch (PackageManagerException e) { 10864 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 10865 + e.getMessage()); 10866 return; 10867 } 10868 // Restore of old package succeeded. Update permissions. 10869 // writer 10870 synchronized (mPackages) { 10871 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 10872 UPDATE_PERMISSIONS_ALL); 10873 // can downgrade to reader 10874 mSettings.writeLPr(); 10875 } 10876 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 10877 } 10878 } 10879 } 10880 10881 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 10882 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 10883 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 10884 String volumeUuid, PackageInstalledInfo res) { 10885 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 10886 + ", old=" + deletedPackage); 10887 boolean disabledSystem = false; 10888 boolean updatedSettings = false; 10889 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 10890 if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 10891 != 0) { 10892 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 10893 } 10894 String packageName = deletedPackage.packageName; 10895 if (packageName == null) { 10896 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10897 "Attempt to delete null packageName."); 10898 return; 10899 } 10900 PackageParser.Package oldPkg; 10901 PackageSetting oldPkgSetting; 10902 // reader 10903 synchronized (mPackages) { 10904 oldPkg = mPackages.get(packageName); 10905 oldPkgSetting = mSettings.mPackages.get(packageName); 10906 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 10907 (oldPkgSetting == null)) { 10908 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10909 "Couldn't find package:" + packageName + " information"); 10910 return; 10911 } 10912 } 10913 10914 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 10915 10916 res.removedInfo.uid = oldPkg.applicationInfo.uid; 10917 res.removedInfo.removedPackage = packageName; 10918 // Remove existing system package 10919 removePackageLI(oldPkgSetting, true); 10920 // writer 10921 synchronized (mPackages) { 10922 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 10923 if (!disabledSystem && deletedPackage != null) { 10924 // We didn't need to disable the .apk as a current system package, 10925 // which means we are replacing another update that is already 10926 // installed. We need to make sure to delete the older one's .apk. 10927 res.removedInfo.args = createInstallArgsForExisting(0, 10928 deletedPackage.applicationInfo.getCodePath(), 10929 deletedPackage.applicationInfo.getResourcePath(), 10930 deletedPackage.applicationInfo.nativeLibraryRootDir, 10931 getAppDexInstructionSets(deletedPackage.applicationInfo)); 10932 } else { 10933 res.removedInfo.args = null; 10934 } 10935 } 10936 10937 // Successfully disabled the old package. Now proceed with re-installation 10938 deleteCodeCacheDirsLI(packageName); 10939 10940 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 10941 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 10942 10943 PackageParser.Package newPackage = null; 10944 try { 10945 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user); 10946 if (newPackage.mExtras != null) { 10947 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 10948 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 10949 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 10950 10951 // is the update attempting to change shared user? that isn't going to work... 10952 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 10953 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 10954 "Forbidding shared user change from " + oldPkgSetting.sharedUser 10955 + " to " + newPkgSetting.sharedUser); 10956 updatedSettings = true; 10957 } 10958 } 10959 10960 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 10961 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 10962 perUserInstalled, res, user); 10963 updatedSettings = true; 10964 } 10965 10966 } catch (PackageManagerException e) { 10967 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10968 } 10969 10970 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10971 // Re installation failed. Restore old information 10972 // Remove new pkg information 10973 if (newPackage != null) { 10974 removeInstalledPackageLI(newPackage, true); 10975 } 10976 // Add back the old system package 10977 try { 10978 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 10979 } catch (PackageManagerException e) { 10980 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 10981 } 10982 // Restore the old system information in Settings 10983 synchronized (mPackages) { 10984 if (disabledSystem) { 10985 mSettings.enableSystemPackageLPw(packageName); 10986 } 10987 if (updatedSettings) { 10988 mSettings.setInstallerPackageName(packageName, 10989 oldPkgSetting.installerPackageName); 10990 } 10991 mSettings.writeLPr(); 10992 } 10993 } 10994 } 10995 10996 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 10997 String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, 10998 UserHandle user) { 10999 String pkgName = newPackage.packageName; 11000 synchronized (mPackages) { 11001 //write settings. the installStatus will be incomplete at this stage. 11002 //note that the new package setting would have already been 11003 //added to mPackages. It hasn't been persisted yet. 11004 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 11005 mSettings.writeLPr(); 11006 } 11007 11008 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 11009 11010 synchronized (mPackages) { 11011 updatePermissionsLPw(newPackage.packageName, newPackage, 11012 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 11013 ? UPDATE_PERMISSIONS_ALL : 0)); 11014 // For system-bundled packages, we assume that installing an upgraded version 11015 // of the package implies that the user actually wants to run that new code, 11016 // so we enable the package. 11017 PackageSetting ps = mSettings.mPackages.get(pkgName); 11018 if (ps != null) { 11019 if (isSystemApp(newPackage)) { 11020 // NB: implicit assumption that system package upgrades apply to all users 11021 if (DEBUG_INSTALL) { 11022 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 11023 } 11024 if (res.origUsers != null) { 11025 for (int userHandle : res.origUsers) { 11026 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 11027 userHandle, installerPackageName); 11028 } 11029 } 11030 // Also convey the prior install/uninstall state 11031 if (allUsers != null && perUserInstalled != null) { 11032 for (int i = 0; i < allUsers.length; i++) { 11033 if (DEBUG_INSTALL) { 11034 Slog.d(TAG, " user " + allUsers[i] 11035 + " => " + perUserInstalled[i]); 11036 } 11037 ps.setInstalled(perUserInstalled[i], allUsers[i]); 11038 } 11039 // these install state changes will be persisted in the 11040 // upcoming call to mSettings.writeLPr(). 11041 } 11042 } 11043 // It's implied that when a user requests installation, they want the app to be 11044 // installed and enabled. 11045 int userId = user.getIdentifier(); 11046 if (userId != UserHandle.USER_ALL) { 11047 ps.setInstalled(true, userId); 11048 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 11049 } 11050 } 11051 res.name = pkgName; 11052 res.uid = newPackage.applicationInfo.uid; 11053 res.pkg = newPackage; 11054 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 11055 mSettings.setInstallerPackageName(pkgName, installerPackageName); 11056 mSettings.setVolumeUuid(pkgName, volumeUuid); 11057 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11058 //to update install status 11059 mSettings.writeLPr(); 11060 } 11061 } 11062 11063 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 11064 final int installFlags = args.installFlags; 11065 final String installerPackageName = args.installerPackageName; 11066 final String volumeUuid = args.volumeUuid; 11067 final File tmpPackageFile = new File(args.getCodePath()); 11068 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 11069 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 11070 || (args.volumeUuid != null)); 11071 boolean replace = false; 11072 final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE; 11073 // Result object to be returned 11074 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11075 11076 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 11077 // Retrieve PackageSettings and parse package 11078 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 11079 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 11080 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 11081 PackageParser pp = new PackageParser(); 11082 pp.setSeparateProcesses(mSeparateProcesses); 11083 pp.setDisplayMetrics(mMetrics); 11084 11085 final PackageParser.Package pkg; 11086 try { 11087 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 11088 } catch (PackageParserException e) { 11089 res.setError("Failed parse during installPackageLI", e); 11090 return; 11091 } 11092 11093 // Mark that we have an install time CPU ABI override. 11094 pkg.cpuAbiOverride = args.abiOverride; 11095 11096 String pkgName = res.name = pkg.packageName; 11097 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 11098 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 11099 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 11100 return; 11101 } 11102 } 11103 11104 try { 11105 pp.collectCertificates(pkg, parseFlags); 11106 pp.collectManifestDigest(pkg); 11107 } catch (PackageParserException e) { 11108 res.setError("Failed collect during installPackageLI", e); 11109 return; 11110 } 11111 11112 /* If the installer passed in a manifest digest, compare it now. */ 11113 if (args.manifestDigest != null) { 11114 if (DEBUG_INSTALL) { 11115 final String parsedManifest = pkg.manifestDigest == null ? "null" 11116 : pkg.manifestDigest.toString(); 11117 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 11118 + parsedManifest); 11119 } 11120 11121 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 11122 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 11123 return; 11124 } 11125 } else if (DEBUG_INSTALL) { 11126 final String parsedManifest = pkg.manifestDigest == null 11127 ? "null" : pkg.manifestDigest.toString(); 11128 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 11129 } 11130 11131 // Get rid of all references to package scan path via parser. 11132 pp = null; 11133 String oldCodePath = null; 11134 boolean systemApp = false; 11135 synchronized (mPackages) { 11136 // Check if installing already existing package 11137 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11138 String oldName = mSettings.mRenamedPackages.get(pkgName); 11139 if (pkg.mOriginalPackages != null 11140 && pkg.mOriginalPackages.contains(oldName) 11141 && mPackages.containsKey(oldName)) { 11142 // This package is derived from an original package, 11143 // and this device has been updating from that original 11144 // name. We must continue using the original name, so 11145 // rename the new package here. 11146 pkg.setPackageName(oldName); 11147 pkgName = pkg.packageName; 11148 replace = true; 11149 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 11150 + oldName + " pkgName=" + pkgName); 11151 } else if (mPackages.containsKey(pkgName)) { 11152 // This package, under its official name, already exists 11153 // on the device; we should replace it. 11154 replace = true; 11155 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 11156 } 11157 } 11158 11159 PackageSetting ps = mSettings.mPackages.get(pkgName); 11160 if (ps != null) { 11161 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 11162 11163 // Quick sanity check that we're signed correctly if updating; 11164 // we'll check this again later when scanning, but we want to 11165 // bail early here before tripping over redefined permissions. 11166 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 11167 try { 11168 verifySignaturesLP(ps, pkg); 11169 } catch (PackageManagerException e) { 11170 res.setError(e.error, e.getMessage()); 11171 return; 11172 } 11173 } else { 11174 if (!checkUpgradeKeySetLP(ps, pkg)) { 11175 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 11176 + pkg.packageName + " upgrade keys do not match the " 11177 + "previously installed version"); 11178 return; 11179 } 11180 } 11181 11182 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 11183 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 11184 systemApp = (ps.pkg.applicationInfo.flags & 11185 ApplicationInfo.FLAG_SYSTEM) != 0; 11186 } 11187 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11188 } 11189 11190 // Check whether the newly-scanned package wants to define an already-defined perm 11191 int N = pkg.permissions.size(); 11192 for (int i = N-1; i >= 0; i--) { 11193 PackageParser.Permission perm = pkg.permissions.get(i); 11194 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 11195 if (bp != null) { 11196 // If the defining package is signed with our cert, it's okay. This 11197 // also includes the "updating the same package" case, of course. 11198 // "updating same package" could also involve key-rotation. 11199 final boolean sigsOk; 11200 if (!bp.sourcePackage.equals(pkg.packageName) 11201 || !(bp.packageSetting instanceof PackageSetting) 11202 || !bp.packageSetting.keySetData.isUsingUpgradeKeySets() 11203 || ((PackageSetting) bp.packageSetting).sharedUser != null) { 11204 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 11205 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 11206 } else { 11207 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 11208 } 11209 if (!sigsOk) { 11210 // If the owning package is the system itself, we log but allow 11211 // install to proceed; we fail the install on all other permission 11212 // redefinitions. 11213 if (!bp.sourcePackage.equals("android")) { 11214 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 11215 + pkg.packageName + " attempting to redeclare permission " 11216 + perm.info.name + " already owned by " + bp.sourcePackage); 11217 res.origPermission = perm.info.name; 11218 res.origPackage = bp.sourcePackage; 11219 return; 11220 } else { 11221 Slog.w(TAG, "Package " + pkg.packageName 11222 + " attempting to redeclare system permission " 11223 + perm.info.name + "; ignoring new declaration"); 11224 pkg.permissions.remove(i); 11225 } 11226 } 11227 } 11228 } 11229 11230 } 11231 11232 if (systemApp && onExternal) { 11233 // Disable updates to system apps on sdcard 11234 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 11235 "Cannot install updates to system apps on sdcard"); 11236 return; 11237 } 11238 11239 // Run dexopt before old package gets removed, to minimize time when app is not available 11240 int result = mPackageDexOptimizer 11241 .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, 11242 false /* defer */, false /* inclDependencies */); 11243 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 11244 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); 11245 return; 11246 } 11247 11248 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 11249 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 11250 return; 11251 } 11252 11253 startIntentFilterVerifications(args.user.getIdentifier(), pkg); 11254 11255 // Call with SCAN_NO_DEX, since dexopt has already been made 11256 if (replace) { 11257 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING | SCAN_NO_DEX, args.user, 11258 installerPackageName, volumeUuid, res); 11259 } else { 11260 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES 11261 | SCAN_NO_DEX, args.user, installerPackageName, volumeUuid, res); 11262 } 11263 synchronized (mPackages) { 11264 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11265 if (ps != null) { 11266 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11267 } 11268 } 11269 } 11270 11271 private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) { 11272 if (mIntentFilterVerifierComponent == null) { 11273 Slog.d(TAG, "No IntentFilter verification will not be done as " 11274 + "there is no IntentFilterVerifier available!"); 11275 return; 11276 } 11277 11278 final int verifierUid = getPackageUid( 11279 mIntentFilterVerifierComponent.getPackageName(), 11280 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId); 11281 11282 mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); 11283 final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 11284 msg.obj = pkg; 11285 msg.arg1 = userId; 11286 msg.arg2 = verifierUid; 11287 11288 mHandler.sendMessage(msg); 11289 } 11290 11291 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, 11292 PackageParser.Package pkg) { 11293 int size = pkg.activities.size(); 11294 if (size == 0) { 11295 Slog.d(TAG, "No activity, so no need to verify any IntentFilter!"); 11296 return; 11297 } 11298 11299 Slog.d(TAG, "Checking for userId:" + userId + " if any IntentFilter from the " + size 11300 + " Activities needs verification ..."); 11301 11302 final int verificationId = mIntentFilterVerificationToken++; 11303 int count = 0; 11304 final String packageName = pkg.packageName; 11305 ArrayList<String> allHosts = new ArrayList<>(); 11306 synchronized (mPackages) { 11307 for (PackageParser.Activity a : pkg.activities) { 11308 for (ActivityIntentInfo filter : a.intents) { 11309 boolean needFilterVerification = filter.needsVerification() && 11310 !filter.isVerified(); 11311 if (needFilterVerification && needNetworkVerificationLPr(filter)) { 11312 Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); 11313 mIntentFilterVerifier.addOneIntentFilterVerification( 11314 verifierUid, userId, verificationId, filter, packageName); 11315 count++; 11316 } else { 11317 Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString()); 11318 if (hasValidDomains(filter)) { 11319 allHosts.addAll(filter.getHostsList()); 11320 } 11321 } 11322 } 11323 } 11324 } 11325 11326 if (count > 0) { 11327 mIntentFilterVerifier.startVerifications(userId); 11328 Slog.d(TAG, "Started " + count + " IntentFilter verification" 11329 + (count > 1 ? "s" : "") + " for userId:" + userId + "!"); 11330 } else { 11331 Slog.d(TAG, "No need to start any IntentFilter verification!"); 11332 if (allHosts.size() > 0 && hasDomainURLs(pkg) && 11333 mSettings.createIntentFilterVerificationIfNeededLPw( 11334 packageName, allHosts) != null) { 11335 scheduleWriteSettingsLocked(); 11336 } 11337 } 11338 } 11339 11340 private boolean needNetworkVerificationLPr(ActivityIntentInfo filter) { 11341 final ComponentName cn = filter.activity.getComponentName(); 11342 final String packageName = cn.getPackageName(); 11343 11344 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 11345 packageName); 11346 if (ivi == null) { 11347 return true; 11348 } 11349 int status = ivi.getStatus(); 11350 switch (status) { 11351 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 11352 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 11353 return true; 11354 11355 default: 11356 // Nothing to do 11357 return false; 11358 } 11359 } 11360 11361 private static boolean isMultiArch(PackageSetting ps) { 11362 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11363 } 11364 11365 private static boolean isMultiArch(ApplicationInfo info) { 11366 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11367 } 11368 11369 private static boolean isExternal(PackageParser.Package pkg) { 11370 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11371 } 11372 11373 private static boolean isExternal(PackageSetting ps) { 11374 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11375 } 11376 11377 private static boolean isExternal(ApplicationInfo info) { 11378 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11379 } 11380 11381 private static boolean isSystemApp(PackageParser.Package pkg) { 11382 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11383 } 11384 11385 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 11386 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 11387 } 11388 11389 private static boolean hasDomainURLs(PackageParser.Package pkg) { 11390 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 11391 } 11392 11393 private static boolean isSystemApp(PackageSetting ps) { 11394 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 11395 } 11396 11397 private static boolean isUpdatedSystemApp(PackageSetting ps) { 11398 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 11399 } 11400 11401 private int packageFlagsToInstallFlags(PackageSetting ps) { 11402 int installFlags = 0; 11403 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 11404 // This existing package was an external ASEC install when we have 11405 // the external flag without a UUID 11406 installFlags |= PackageManager.INSTALL_EXTERNAL; 11407 } 11408 if (ps.isForwardLocked()) { 11409 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 11410 } 11411 return installFlags; 11412 } 11413 11414 private void deleteTempPackageFiles() { 11415 final FilenameFilter filter = new FilenameFilter() { 11416 public boolean accept(File dir, String name) { 11417 return name.startsWith("vmdl") && name.endsWith(".tmp"); 11418 } 11419 }; 11420 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 11421 file.delete(); 11422 } 11423 } 11424 11425 @Override 11426 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 11427 int flags) { 11428 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 11429 flags); 11430 } 11431 11432 @Override 11433 public void deletePackage(final String packageName, 11434 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 11435 mContext.enforceCallingOrSelfPermission( 11436 android.Manifest.permission.DELETE_PACKAGES, null); 11437 final int uid = Binder.getCallingUid(); 11438 if (UserHandle.getUserId(uid) != userId) { 11439 mContext.enforceCallingPermission( 11440 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11441 "deletePackage for user " + userId); 11442 } 11443 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 11444 try { 11445 observer.onPackageDeleted(packageName, 11446 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 11447 } catch (RemoteException re) { 11448 } 11449 return; 11450 } 11451 11452 boolean uninstallBlocked = false; 11453 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 11454 int[] users = sUserManager.getUserIds(); 11455 for (int i = 0; i < users.length; ++i) { 11456 if (getBlockUninstallForUser(packageName, users[i])) { 11457 uninstallBlocked = true; 11458 break; 11459 } 11460 } 11461 } else { 11462 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 11463 } 11464 if (uninstallBlocked) { 11465 try { 11466 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 11467 null); 11468 } catch (RemoteException re) { 11469 } 11470 return; 11471 } 11472 11473 if (DEBUG_REMOVE) { 11474 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 11475 } 11476 // Queue up an async operation since the package deletion may take a little while. 11477 mHandler.post(new Runnable() { 11478 public void run() { 11479 mHandler.removeCallbacks(this); 11480 final int returnCode = deletePackageX(packageName, userId, flags); 11481 if (observer != null) { 11482 try { 11483 observer.onPackageDeleted(packageName, returnCode, null); 11484 } catch (RemoteException e) { 11485 Log.i(TAG, "Observer no longer exists."); 11486 } //end catch 11487 } //end if 11488 } //end run 11489 }); 11490 } 11491 11492 private boolean isPackageDeviceAdmin(String packageName, int userId) { 11493 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 11494 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 11495 try { 11496 if (dpm != null) { 11497 if (dpm.isDeviceOwner(packageName)) { 11498 return true; 11499 } 11500 int[] users; 11501 if (userId == UserHandle.USER_ALL) { 11502 users = sUserManager.getUserIds(); 11503 } else { 11504 users = new int[]{userId}; 11505 } 11506 for (int i = 0; i < users.length; ++i) { 11507 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 11508 return true; 11509 } 11510 } 11511 } 11512 } catch (RemoteException e) { 11513 } 11514 return false; 11515 } 11516 11517 /** 11518 * This method is an internal method that could be get invoked either 11519 * to delete an installed package or to clean up a failed installation. 11520 * After deleting an installed package, a broadcast is sent to notify any 11521 * listeners that the package has been installed. For cleaning up a failed 11522 * installation, the broadcast is not necessary since the package's 11523 * installation wouldn't have sent the initial broadcast either 11524 * The key steps in deleting a package are 11525 * deleting the package information in internal structures like mPackages, 11526 * deleting the packages base directories through installd 11527 * updating mSettings to reflect current status 11528 * persisting settings for later use 11529 * sending a broadcast if necessary 11530 */ 11531 private int deletePackageX(String packageName, int userId, int flags) { 11532 final PackageRemovedInfo info = new PackageRemovedInfo(); 11533 final boolean res; 11534 11535 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 11536 ? UserHandle.ALL : new UserHandle(userId); 11537 11538 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 11539 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 11540 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 11541 } 11542 11543 boolean removedForAllUsers = false; 11544 boolean systemUpdate = false; 11545 11546 // for the uninstall-updates case and restricted profiles, remember the per- 11547 // userhandle installed state 11548 int[] allUsers; 11549 boolean[] perUserInstalled; 11550 synchronized (mPackages) { 11551 PackageSetting ps = mSettings.mPackages.get(packageName); 11552 allUsers = sUserManager.getUserIds(); 11553 perUserInstalled = new boolean[allUsers.length]; 11554 for (int i = 0; i < allUsers.length; i++) { 11555 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 11556 } 11557 } 11558 11559 synchronized (mInstallLock) { 11560 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 11561 res = deletePackageLI(packageName, removeForUser, 11562 true, allUsers, perUserInstalled, 11563 flags | REMOVE_CHATTY, info, true); 11564 systemUpdate = info.isRemovedPackageSystemUpdate; 11565 if (res && !systemUpdate && mPackages.get(packageName) == null) { 11566 removedForAllUsers = true; 11567 } 11568 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 11569 + " removedForAllUsers=" + removedForAllUsers); 11570 } 11571 11572 if (res) { 11573 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 11574 11575 // If the removed package was a system update, the old system package 11576 // was re-enabled; we need to broadcast this information 11577 if (systemUpdate) { 11578 Bundle extras = new Bundle(1); 11579 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 11580 ? info.removedAppId : info.uid); 11581 extras.putBoolean(Intent.EXTRA_REPLACING, true); 11582 11583 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 11584 extras, null, null, null); 11585 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 11586 extras, null, null, null); 11587 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 11588 null, packageName, null, null); 11589 } 11590 } 11591 // Force a gc here. 11592 Runtime.getRuntime().gc(); 11593 // Delete the resources here after sending the broadcast to let 11594 // other processes clean up before deleting resources. 11595 if (info.args != null) { 11596 synchronized (mInstallLock) { 11597 info.args.doPostDeleteLI(true); 11598 } 11599 } 11600 11601 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 11602 } 11603 11604 static class PackageRemovedInfo { 11605 String removedPackage; 11606 int uid = -1; 11607 int removedAppId = -1; 11608 int[] removedUsers = null; 11609 boolean isRemovedPackageSystemUpdate = false; 11610 // Clean up resources deleted packages. 11611 InstallArgs args = null; 11612 11613 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 11614 Bundle extras = new Bundle(1); 11615 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 11616 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 11617 if (replacing) { 11618 extras.putBoolean(Intent.EXTRA_REPLACING, true); 11619 } 11620 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 11621 if (removedPackage != null) { 11622 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 11623 extras, null, null, removedUsers); 11624 if (fullRemove && !replacing) { 11625 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 11626 extras, null, null, removedUsers); 11627 } 11628 } 11629 if (removedAppId >= 0) { 11630 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 11631 removedUsers); 11632 } 11633 } 11634 } 11635 11636 /* 11637 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 11638 * flag is not set, the data directory is removed as well. 11639 * make sure this flag is set for partially installed apps. If not its meaningless to 11640 * delete a partially installed application. 11641 */ 11642 private void removePackageDataLI(PackageSetting ps, 11643 int[] allUserHandles, boolean[] perUserInstalled, 11644 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 11645 String packageName = ps.name; 11646 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 11647 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 11648 // Retrieve object to delete permissions for shared user later on 11649 final PackageSetting deletedPs; 11650 // reader 11651 synchronized (mPackages) { 11652 deletedPs = mSettings.mPackages.get(packageName); 11653 if (outInfo != null) { 11654 outInfo.removedPackage = packageName; 11655 outInfo.removedUsers = deletedPs != null 11656 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 11657 : null; 11658 } 11659 } 11660 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11661 removeDataDirsLI(packageName); 11662 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 11663 } 11664 // writer 11665 synchronized (mPackages) { 11666 if (deletedPs != null) { 11667 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11668 if (outInfo != null) { 11669 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 11670 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 11671 } 11672 updatePermissionsLPw(deletedPs.name, null, 0); 11673 if (deletedPs.sharedUser != null) { 11674 // Remove permissions associated with package. Since runtime 11675 // permissions are per user we have to kill the removed package 11676 // or packages running under the shared user of the removed 11677 // package if revoking the permissions requested only by the removed 11678 // package is successful and this causes a change in gids. 11679 for (int userId : UserManagerService.getInstance().getUserIds()) { 11680 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 11681 userId); 11682 if (userIdToKill == UserHandle.USER_ALL 11683 || userIdToKill >= UserHandle.USER_OWNER) { 11684 // If gids changed for this user, kill all affected packages. 11685 mHandler.post(new Runnable() { 11686 @Override 11687 public void run() { 11688 // This has to happen with no lock held. 11689 killSettingPackagesForUser(deletedPs, userIdToKill, 11690 KILL_APP_REASON_GIDS_CHANGED); 11691 } 11692 }); 11693 break; 11694 } 11695 } 11696 } 11697 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 11698 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 11699 } 11700 // make sure to preserve per-user disabled state if this removal was just 11701 // a downgrade of a system app to the factory package 11702 if (allUserHandles != null && perUserInstalled != null) { 11703 if (DEBUG_REMOVE) { 11704 Slog.d(TAG, "Propagating install state across downgrade"); 11705 } 11706 for (int i = 0; i < allUserHandles.length; i++) { 11707 if (DEBUG_REMOVE) { 11708 Slog.d(TAG, " user " + allUserHandles[i] 11709 + " => " + perUserInstalled[i]); 11710 } 11711 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 11712 } 11713 } 11714 } 11715 // can downgrade to reader 11716 if (writeSettings) { 11717 // Save settings now 11718 mSettings.writeLPr(); 11719 } 11720 } 11721 if (outInfo != null) { 11722 // A user ID was deleted here. Go through all users and remove it 11723 // from KeyStore. 11724 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 11725 } 11726 } 11727 11728 static boolean locationIsPrivileged(File path) { 11729 try { 11730 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 11731 .getCanonicalPath(); 11732 return path.getCanonicalPath().startsWith(privilegedAppDir); 11733 } catch (IOException e) { 11734 Slog.e(TAG, "Unable to access code path " + path); 11735 } 11736 return false; 11737 } 11738 11739 /* 11740 * Tries to delete system package. 11741 */ 11742 private boolean deleteSystemPackageLI(PackageSetting newPs, 11743 int[] allUserHandles, boolean[] perUserInstalled, 11744 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 11745 final boolean applyUserRestrictions 11746 = (allUserHandles != null) && (perUserInstalled != null); 11747 PackageSetting disabledPs = null; 11748 // Confirm if the system package has been updated 11749 // An updated system app can be deleted. This will also have to restore 11750 // the system pkg from system partition 11751 // reader 11752 synchronized (mPackages) { 11753 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 11754 } 11755 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 11756 + " disabledPs=" + disabledPs); 11757 if (disabledPs == null) { 11758 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 11759 return false; 11760 } else if (DEBUG_REMOVE) { 11761 Slog.d(TAG, "Deleting system pkg from data partition"); 11762 } 11763 if (DEBUG_REMOVE) { 11764 if (applyUserRestrictions) { 11765 Slog.d(TAG, "Remembering install states:"); 11766 for (int i = 0; i < allUserHandles.length; i++) { 11767 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 11768 } 11769 } 11770 } 11771 // Delete the updated package 11772 outInfo.isRemovedPackageSystemUpdate = true; 11773 if (disabledPs.versionCode < newPs.versionCode) { 11774 // Delete data for downgrades 11775 flags &= ~PackageManager.DELETE_KEEP_DATA; 11776 } else { 11777 // Preserve data by setting flag 11778 flags |= PackageManager.DELETE_KEEP_DATA; 11779 } 11780 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 11781 allUserHandles, perUserInstalled, outInfo, writeSettings); 11782 if (!ret) { 11783 return false; 11784 } 11785 // writer 11786 synchronized (mPackages) { 11787 // Reinstate the old system package 11788 mSettings.enableSystemPackageLPw(newPs.name); 11789 // Remove any native libraries from the upgraded package. 11790 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 11791 } 11792 // Install the system package 11793 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 11794 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 11795 if (locationIsPrivileged(disabledPs.codePath)) { 11796 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 11797 } 11798 11799 final PackageParser.Package newPkg; 11800 try { 11801 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 11802 } catch (PackageManagerException e) { 11803 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 11804 return false; 11805 } 11806 11807 // writer 11808 synchronized (mPackages) { 11809 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 11810 updatePermissionsLPw(newPkg.packageName, newPkg, 11811 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 11812 if (applyUserRestrictions) { 11813 if (DEBUG_REMOVE) { 11814 Slog.d(TAG, "Propagating install state across reinstall"); 11815 } 11816 for (int i = 0; i < allUserHandles.length; i++) { 11817 if (DEBUG_REMOVE) { 11818 Slog.d(TAG, " user " + allUserHandles[i] 11819 + " => " + perUserInstalled[i]); 11820 } 11821 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 11822 } 11823 // Regardless of writeSettings we need to ensure that this restriction 11824 // state propagation is persisted 11825 mSettings.writeAllUsersPackageRestrictionsLPr(); 11826 } 11827 // can downgrade to reader here 11828 if (writeSettings) { 11829 mSettings.writeLPr(); 11830 } 11831 } 11832 return true; 11833 } 11834 11835 private boolean deleteInstalledPackageLI(PackageSetting ps, 11836 boolean deleteCodeAndResources, int flags, 11837 int[] allUserHandles, boolean[] perUserInstalled, 11838 PackageRemovedInfo outInfo, boolean writeSettings) { 11839 if (outInfo != null) { 11840 outInfo.uid = ps.appId; 11841 } 11842 11843 // Delete package data from internal structures and also remove data if flag is set 11844 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 11845 11846 // Delete application code and resources 11847 if (deleteCodeAndResources && (outInfo != null)) { 11848 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 11849 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 11850 getAppDexInstructionSets(ps)); 11851 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 11852 } 11853 return true; 11854 } 11855 11856 @Override 11857 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 11858 int userId) { 11859 mContext.enforceCallingOrSelfPermission( 11860 android.Manifest.permission.DELETE_PACKAGES, null); 11861 synchronized (mPackages) { 11862 PackageSetting ps = mSettings.mPackages.get(packageName); 11863 if (ps == null) { 11864 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 11865 return false; 11866 } 11867 if (!ps.getInstalled(userId)) { 11868 // Can't block uninstall for an app that is not installed or enabled. 11869 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 11870 return false; 11871 } 11872 ps.setBlockUninstall(blockUninstall, userId); 11873 mSettings.writePackageRestrictionsLPr(userId); 11874 } 11875 return true; 11876 } 11877 11878 @Override 11879 public boolean getBlockUninstallForUser(String packageName, int userId) { 11880 synchronized (mPackages) { 11881 PackageSetting ps = mSettings.mPackages.get(packageName); 11882 if (ps == null) { 11883 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 11884 return false; 11885 } 11886 return ps.getBlockUninstall(userId); 11887 } 11888 } 11889 11890 /* 11891 * This method handles package deletion in general 11892 */ 11893 private boolean deletePackageLI(String packageName, UserHandle user, 11894 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 11895 int flags, PackageRemovedInfo outInfo, 11896 boolean writeSettings) { 11897 if (packageName == null) { 11898 Slog.w(TAG, "Attempt to delete null packageName."); 11899 return false; 11900 } 11901 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 11902 PackageSetting ps; 11903 boolean dataOnly = false; 11904 int removeUser = -1; 11905 int appId = -1; 11906 synchronized (mPackages) { 11907 ps = mSettings.mPackages.get(packageName); 11908 if (ps == null) { 11909 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 11910 return false; 11911 } 11912 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 11913 && user.getIdentifier() != UserHandle.USER_ALL) { 11914 // The caller is asking that the package only be deleted for a single 11915 // user. To do this, we just mark its uninstalled state and delete 11916 // its data. If this is a system app, we only allow this to happen if 11917 // they have set the special DELETE_SYSTEM_APP which requests different 11918 // semantics than normal for uninstalling system apps. 11919 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 11920 ps.setUserState(user.getIdentifier(), 11921 COMPONENT_ENABLED_STATE_DEFAULT, 11922 false, //installed 11923 true, //stopped 11924 true, //notLaunched 11925 false, //hidden 11926 null, null, null, 11927 false, // blockUninstall 11928 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 11929 if (!isSystemApp(ps)) { 11930 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 11931 // Other user still have this package installed, so all 11932 // we need to do is clear this user's data and save that 11933 // it is uninstalled. 11934 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 11935 removeUser = user.getIdentifier(); 11936 appId = ps.appId; 11937 mSettings.writePackageRestrictionsLPr(removeUser); 11938 } else { 11939 // We need to set it back to 'installed' so the uninstall 11940 // broadcasts will be sent correctly. 11941 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 11942 ps.setInstalled(true, user.getIdentifier()); 11943 } 11944 } else { 11945 // This is a system app, so we assume that the 11946 // other users still have this package installed, so all 11947 // we need to do is clear this user's data and save that 11948 // it is uninstalled. 11949 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 11950 removeUser = user.getIdentifier(); 11951 appId = ps.appId; 11952 mSettings.writePackageRestrictionsLPr(removeUser); 11953 } 11954 } 11955 } 11956 11957 if (removeUser >= 0) { 11958 // From above, we determined that we are deleting this only 11959 // for a single user. Continue the work here. 11960 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 11961 if (outInfo != null) { 11962 outInfo.removedPackage = packageName; 11963 outInfo.removedAppId = appId; 11964 outInfo.removedUsers = new int[] {removeUser}; 11965 } 11966 mInstaller.clearUserData(packageName, removeUser); 11967 removeKeystoreDataIfNeeded(removeUser, appId); 11968 schedulePackageCleaning(packageName, removeUser, false); 11969 return true; 11970 } 11971 11972 if (dataOnly) { 11973 // Delete application data first 11974 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 11975 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 11976 return true; 11977 } 11978 11979 boolean ret = false; 11980 if (isSystemApp(ps)) { 11981 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 11982 // When an updated system application is deleted we delete the existing resources as well and 11983 // fall back to existing code in system partition 11984 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 11985 flags, outInfo, writeSettings); 11986 } else { 11987 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 11988 // Kill application pre-emptively especially for apps on sd. 11989 killApplication(packageName, ps.appId, "uninstall pkg"); 11990 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 11991 allUserHandles, perUserInstalled, 11992 outInfo, writeSettings); 11993 } 11994 11995 return ret; 11996 } 11997 11998 private final class ClearStorageConnection implements ServiceConnection { 11999 IMediaContainerService mContainerService; 12000 12001 @Override 12002 public void onServiceConnected(ComponentName name, IBinder service) { 12003 synchronized (this) { 12004 mContainerService = IMediaContainerService.Stub.asInterface(service); 12005 notifyAll(); 12006 } 12007 } 12008 12009 @Override 12010 public void onServiceDisconnected(ComponentName name) { 12011 } 12012 } 12013 12014 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 12015 final boolean mounted; 12016 if (Environment.isExternalStorageEmulated()) { 12017 mounted = true; 12018 } else { 12019 final String status = Environment.getExternalStorageState(); 12020 12021 mounted = status.equals(Environment.MEDIA_MOUNTED) 12022 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 12023 } 12024 12025 if (!mounted) { 12026 return; 12027 } 12028 12029 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 12030 int[] users; 12031 if (userId == UserHandle.USER_ALL) { 12032 users = sUserManager.getUserIds(); 12033 } else { 12034 users = new int[] { userId }; 12035 } 12036 final ClearStorageConnection conn = new ClearStorageConnection(); 12037 if (mContext.bindServiceAsUser( 12038 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 12039 try { 12040 for (int curUser : users) { 12041 long timeout = SystemClock.uptimeMillis() + 5000; 12042 synchronized (conn) { 12043 long now = SystemClock.uptimeMillis(); 12044 while (conn.mContainerService == null && now < timeout) { 12045 try { 12046 conn.wait(timeout - now); 12047 } catch (InterruptedException e) { 12048 } 12049 } 12050 } 12051 if (conn.mContainerService == null) { 12052 return; 12053 } 12054 12055 final UserEnvironment userEnv = new UserEnvironment(curUser); 12056 clearDirectory(conn.mContainerService, 12057 userEnv.buildExternalStorageAppCacheDirs(packageName)); 12058 if (allData) { 12059 clearDirectory(conn.mContainerService, 12060 userEnv.buildExternalStorageAppDataDirs(packageName)); 12061 clearDirectory(conn.mContainerService, 12062 userEnv.buildExternalStorageAppMediaDirs(packageName)); 12063 } 12064 } 12065 } finally { 12066 mContext.unbindService(conn); 12067 } 12068 } 12069 } 12070 12071 @Override 12072 public void clearApplicationUserData(final String packageName, 12073 final IPackageDataObserver observer, final int userId) { 12074 mContext.enforceCallingOrSelfPermission( 12075 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 12076 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 12077 // Queue up an async operation since the package deletion may take a little while. 12078 mHandler.post(new Runnable() { 12079 public void run() { 12080 mHandler.removeCallbacks(this); 12081 final boolean succeeded; 12082 synchronized (mInstallLock) { 12083 succeeded = clearApplicationUserDataLI(packageName, userId); 12084 } 12085 clearExternalStorageDataSync(packageName, userId, true); 12086 if (succeeded) { 12087 // invoke DeviceStorageMonitor's update method to clear any notifications 12088 DeviceStorageMonitorInternal 12089 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 12090 if (dsm != null) { 12091 dsm.checkMemory(); 12092 } 12093 } 12094 if(observer != null) { 12095 try { 12096 observer.onRemoveCompleted(packageName, succeeded); 12097 } catch (RemoteException e) { 12098 Log.i(TAG, "Observer no longer exists."); 12099 } 12100 } //end if observer 12101 } //end run 12102 }); 12103 } 12104 12105 private boolean clearApplicationUserDataLI(String packageName, int userId) { 12106 if (packageName == null) { 12107 Slog.w(TAG, "Attempt to delete null packageName."); 12108 return false; 12109 } 12110 12111 // Try finding details about the requested package 12112 PackageParser.Package pkg; 12113 synchronized (mPackages) { 12114 pkg = mPackages.get(packageName); 12115 if (pkg == null) { 12116 final PackageSetting ps = mSettings.mPackages.get(packageName); 12117 if (ps != null) { 12118 pkg = ps.pkg; 12119 } 12120 } 12121 } 12122 12123 if (pkg == null) { 12124 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 12125 } 12126 12127 // Always delete data directories for package, even if we found no other 12128 // record of app. This helps users recover from UID mismatches without 12129 // resorting to a full data wipe. 12130 int retCode = mInstaller.clearUserData(packageName, userId); 12131 if (retCode < 0) { 12132 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 12133 return false; 12134 } 12135 12136 if (pkg == null) { 12137 return false; 12138 } 12139 12140 if (pkg != null && pkg.applicationInfo != null) { 12141 final int appId = pkg.applicationInfo.uid; 12142 removeKeystoreDataIfNeeded(userId, appId); 12143 } 12144 12145 // Create a native library symlink only if we have native libraries 12146 // and if the native libraries are 32 bit libraries. We do not provide 12147 // this symlink for 64 bit libraries. 12148 if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null && 12149 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 12150 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 12151 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) { 12152 Slog.w(TAG, "Failed linking native library dir"); 12153 return false; 12154 } 12155 } 12156 12157 return true; 12158 } 12159 12160 /** 12161 * Remove entries from the keystore daemon. Will only remove it if the 12162 * {@code appId} is valid. 12163 */ 12164 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 12165 if (appId < 0) { 12166 return; 12167 } 12168 12169 final KeyStore keyStore = KeyStore.getInstance(); 12170 if (keyStore != null) { 12171 if (userId == UserHandle.USER_ALL) { 12172 for (final int individual : sUserManager.getUserIds()) { 12173 keyStore.clearUid(UserHandle.getUid(individual, appId)); 12174 } 12175 } else { 12176 keyStore.clearUid(UserHandle.getUid(userId, appId)); 12177 } 12178 } else { 12179 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 12180 } 12181 } 12182 12183 @Override 12184 public void deleteApplicationCacheFiles(final String packageName, 12185 final IPackageDataObserver observer) { 12186 mContext.enforceCallingOrSelfPermission( 12187 android.Manifest.permission.DELETE_CACHE_FILES, null); 12188 // Queue up an async operation since the package deletion may take a little while. 12189 final int userId = UserHandle.getCallingUserId(); 12190 mHandler.post(new Runnable() { 12191 public void run() { 12192 mHandler.removeCallbacks(this); 12193 final boolean succeded; 12194 synchronized (mInstallLock) { 12195 succeded = deleteApplicationCacheFilesLI(packageName, userId); 12196 } 12197 clearExternalStorageDataSync(packageName, userId, false); 12198 if(observer != null) { 12199 try { 12200 observer.onRemoveCompleted(packageName, succeded); 12201 } catch (RemoteException e) { 12202 Log.i(TAG, "Observer no longer exists."); 12203 } 12204 } //end if observer 12205 } //end run 12206 }); 12207 } 12208 12209 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 12210 if (packageName == null) { 12211 Slog.w(TAG, "Attempt to delete null packageName."); 12212 return false; 12213 } 12214 PackageParser.Package p; 12215 synchronized (mPackages) { 12216 p = mPackages.get(packageName); 12217 } 12218 if (p == null) { 12219 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12220 return false; 12221 } 12222 final ApplicationInfo applicationInfo = p.applicationInfo; 12223 if (applicationInfo == null) { 12224 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12225 return false; 12226 } 12227 int retCode = mInstaller.deleteCacheFiles(packageName, userId); 12228 if (retCode < 0) { 12229 Slog.w(TAG, "Couldn't remove cache files for package: " 12230 + packageName + " u" + userId); 12231 return false; 12232 } 12233 return true; 12234 } 12235 12236 @Override 12237 public void getPackageSizeInfo(final String packageName, int userHandle, 12238 final IPackageStatsObserver observer) { 12239 mContext.enforceCallingOrSelfPermission( 12240 android.Manifest.permission.GET_PACKAGE_SIZE, null); 12241 if (packageName == null) { 12242 throw new IllegalArgumentException("Attempt to get size of null packageName"); 12243 } 12244 12245 PackageStats stats = new PackageStats(packageName, userHandle); 12246 12247 /* 12248 * Queue up an async operation since the package measurement may take a 12249 * little while. 12250 */ 12251 Message msg = mHandler.obtainMessage(INIT_COPY); 12252 msg.obj = new MeasureParams(stats, observer); 12253 mHandler.sendMessage(msg); 12254 } 12255 12256 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 12257 PackageStats pStats) { 12258 if (packageName == null) { 12259 Slog.w(TAG, "Attempt to get size of null packageName."); 12260 return false; 12261 } 12262 PackageParser.Package p; 12263 boolean dataOnly = false; 12264 String libDirRoot = null; 12265 String asecPath = null; 12266 PackageSetting ps = null; 12267 synchronized (mPackages) { 12268 p = mPackages.get(packageName); 12269 ps = mSettings.mPackages.get(packageName); 12270 if(p == null) { 12271 dataOnly = true; 12272 if((ps == null) || (ps.pkg == null)) { 12273 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12274 return false; 12275 } 12276 p = ps.pkg; 12277 } 12278 if (ps != null) { 12279 libDirRoot = ps.legacyNativeLibraryPathString; 12280 } 12281 if (p != null && (isExternal(p) || p.isForwardLocked())) { 12282 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 12283 if (secureContainerId != null) { 12284 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 12285 } 12286 } 12287 } 12288 String publicSrcDir = null; 12289 if(!dataOnly) { 12290 final ApplicationInfo applicationInfo = p.applicationInfo; 12291 if (applicationInfo == null) { 12292 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12293 return false; 12294 } 12295 if (p.isForwardLocked()) { 12296 publicSrcDir = applicationInfo.getBaseResourcePath(); 12297 } 12298 } 12299 // TODO: extend to measure size of split APKs 12300 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 12301 // not just the first level. 12302 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 12303 // just the primary. 12304 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 12305 int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot, 12306 publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 12307 if (res < 0) { 12308 return false; 12309 } 12310 12311 // Fix-up for forward-locked applications in ASEC containers. 12312 if (!isExternal(p)) { 12313 pStats.codeSize += pStats.externalCodeSize; 12314 pStats.externalCodeSize = 0L; 12315 } 12316 12317 return true; 12318 } 12319 12320 12321 @Override 12322 public void addPackageToPreferred(String packageName) { 12323 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 12324 } 12325 12326 @Override 12327 public void removePackageFromPreferred(String packageName) { 12328 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 12329 } 12330 12331 @Override 12332 public List<PackageInfo> getPreferredPackages(int flags) { 12333 return new ArrayList<PackageInfo>(); 12334 } 12335 12336 private int getUidTargetSdkVersionLockedLPr(int uid) { 12337 Object obj = mSettings.getUserIdLPr(uid); 12338 if (obj instanceof SharedUserSetting) { 12339 final SharedUserSetting sus = (SharedUserSetting) obj; 12340 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 12341 final Iterator<PackageSetting> it = sus.packages.iterator(); 12342 while (it.hasNext()) { 12343 final PackageSetting ps = it.next(); 12344 if (ps.pkg != null) { 12345 int v = ps.pkg.applicationInfo.targetSdkVersion; 12346 if (v < vers) vers = v; 12347 } 12348 } 12349 return vers; 12350 } else if (obj instanceof PackageSetting) { 12351 final PackageSetting ps = (PackageSetting) obj; 12352 if (ps.pkg != null) { 12353 return ps.pkg.applicationInfo.targetSdkVersion; 12354 } 12355 } 12356 return Build.VERSION_CODES.CUR_DEVELOPMENT; 12357 } 12358 12359 @Override 12360 public void addPreferredActivity(IntentFilter filter, int match, 12361 ComponentName[] set, ComponentName activity, int userId) { 12362 addPreferredActivityInternal(filter, match, set, activity, true, userId, 12363 "Adding preferred"); 12364 } 12365 12366 private void addPreferredActivityInternal(IntentFilter filter, int match, 12367 ComponentName[] set, ComponentName activity, boolean always, int userId, 12368 String opname) { 12369 // writer 12370 int callingUid = Binder.getCallingUid(); 12371 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 12372 if (filter.countActions() == 0) { 12373 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 12374 return; 12375 } 12376 synchronized (mPackages) { 12377 if (mContext.checkCallingOrSelfPermission( 12378 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12379 != PackageManager.PERMISSION_GRANTED) { 12380 if (getUidTargetSdkVersionLockedLPr(callingUid) 12381 < Build.VERSION_CODES.FROYO) { 12382 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 12383 + callingUid); 12384 return; 12385 } 12386 mContext.enforceCallingOrSelfPermission( 12387 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12388 } 12389 12390 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 12391 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 12392 + userId + ":"); 12393 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12394 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 12395 scheduleWritePackageRestrictionsLocked(userId); 12396 } 12397 } 12398 12399 @Override 12400 public void replacePreferredActivity(IntentFilter filter, int match, 12401 ComponentName[] set, ComponentName activity, int userId) { 12402 if (filter.countActions() != 1) { 12403 throw new IllegalArgumentException( 12404 "replacePreferredActivity expects filter to have only 1 action."); 12405 } 12406 if (filter.countDataAuthorities() != 0 12407 || filter.countDataPaths() != 0 12408 || filter.countDataSchemes() > 1 12409 || filter.countDataTypes() != 0) { 12410 throw new IllegalArgumentException( 12411 "replacePreferredActivity expects filter to have no data authorities, " + 12412 "paths, or types; and at most one scheme."); 12413 } 12414 12415 final int callingUid = Binder.getCallingUid(); 12416 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 12417 synchronized (mPackages) { 12418 if (mContext.checkCallingOrSelfPermission( 12419 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12420 != PackageManager.PERMISSION_GRANTED) { 12421 if (getUidTargetSdkVersionLockedLPr(callingUid) 12422 < Build.VERSION_CODES.FROYO) { 12423 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 12424 + Binder.getCallingUid()); 12425 return; 12426 } 12427 mContext.enforceCallingOrSelfPermission( 12428 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12429 } 12430 12431 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 12432 if (pir != null) { 12433 // Get all of the existing entries that exactly match this filter. 12434 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 12435 if (existing != null && existing.size() == 1) { 12436 PreferredActivity cur = existing.get(0); 12437 if (DEBUG_PREFERRED) { 12438 Slog.i(TAG, "Checking replace of preferred:"); 12439 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12440 if (!cur.mPref.mAlways) { 12441 Slog.i(TAG, " -- CUR; not mAlways!"); 12442 } else { 12443 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 12444 Slog.i(TAG, " -- CUR: mSet=" 12445 + Arrays.toString(cur.mPref.mSetComponents)); 12446 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 12447 Slog.i(TAG, " -- NEW: mMatch=" 12448 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 12449 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 12450 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 12451 } 12452 } 12453 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 12454 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 12455 && cur.mPref.sameSet(set)) { 12456 // Setting the preferred activity to what it happens to be already 12457 if (DEBUG_PREFERRED) { 12458 Slog.i(TAG, "Replacing with same preferred activity " 12459 + cur.mPref.mShortComponent + " for user " 12460 + userId + ":"); 12461 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12462 } 12463 return; 12464 } 12465 } 12466 12467 if (existing != null) { 12468 if (DEBUG_PREFERRED) { 12469 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 12470 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12471 } 12472 for (int i = 0; i < existing.size(); i++) { 12473 PreferredActivity pa = existing.get(i); 12474 if (DEBUG_PREFERRED) { 12475 Slog.i(TAG, "Removing existing preferred activity " 12476 + pa.mPref.mComponent + ":"); 12477 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 12478 } 12479 pir.removeFilter(pa); 12480 } 12481 } 12482 } 12483 addPreferredActivityInternal(filter, match, set, activity, true, userId, 12484 "Replacing preferred"); 12485 } 12486 } 12487 12488 @Override 12489 public void clearPackagePreferredActivities(String packageName) { 12490 final int uid = Binder.getCallingUid(); 12491 // writer 12492 synchronized (mPackages) { 12493 PackageParser.Package pkg = mPackages.get(packageName); 12494 if (pkg == null || pkg.applicationInfo.uid != uid) { 12495 if (mContext.checkCallingOrSelfPermission( 12496 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12497 != PackageManager.PERMISSION_GRANTED) { 12498 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 12499 < Build.VERSION_CODES.FROYO) { 12500 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 12501 + Binder.getCallingUid()); 12502 return; 12503 } 12504 mContext.enforceCallingOrSelfPermission( 12505 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12506 } 12507 } 12508 12509 int user = UserHandle.getCallingUserId(); 12510 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 12511 scheduleWritePackageRestrictionsLocked(user); 12512 } 12513 } 12514 } 12515 12516 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 12517 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 12518 ArrayList<PreferredActivity> removed = null; 12519 boolean changed = false; 12520 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 12521 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 12522 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 12523 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 12524 continue; 12525 } 12526 Iterator<PreferredActivity> it = pir.filterIterator(); 12527 while (it.hasNext()) { 12528 PreferredActivity pa = it.next(); 12529 // Mark entry for removal only if it matches the package name 12530 // and the entry is of type "always". 12531 if (packageName == null || 12532 (pa.mPref.mComponent.getPackageName().equals(packageName) 12533 && pa.mPref.mAlways)) { 12534 if (removed == null) { 12535 removed = new ArrayList<PreferredActivity>(); 12536 } 12537 removed.add(pa); 12538 } 12539 } 12540 if (removed != null) { 12541 for (int j=0; j<removed.size(); j++) { 12542 PreferredActivity pa = removed.get(j); 12543 pir.removeFilter(pa); 12544 } 12545 changed = true; 12546 } 12547 } 12548 return changed; 12549 } 12550 12551 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 12552 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 12553 if (userId == UserHandle.USER_ALL) { 12554 mSettings.removeIntentFilterVerificationLPw(packageName, sUserManager.getUserIds()); 12555 for (int oneUserId : sUserManager.getUserIds()) { 12556 scheduleWritePackageRestrictionsLocked(oneUserId); 12557 } 12558 } else { 12559 mSettings.removeIntentFilterVerificationLPw(packageName, userId); 12560 scheduleWritePackageRestrictionsLocked(userId); 12561 } 12562 } 12563 12564 @Override 12565 public void resetPreferredActivities(int userId) { 12566 /* TODO: Actually use userId. Why is it being passed in? */ 12567 mContext.enforceCallingOrSelfPermission( 12568 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12569 // writer 12570 synchronized (mPackages) { 12571 int user = UserHandle.getCallingUserId(); 12572 clearPackagePreferredActivitiesLPw(null, user); 12573 mSettings.readDefaultPreferredAppsLPw(this, user); 12574 scheduleWritePackageRestrictionsLocked(user); 12575 } 12576 } 12577 12578 @Override 12579 public int getPreferredActivities(List<IntentFilter> outFilters, 12580 List<ComponentName> outActivities, String packageName) { 12581 12582 int num = 0; 12583 final int userId = UserHandle.getCallingUserId(); 12584 // reader 12585 synchronized (mPackages) { 12586 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 12587 if (pir != null) { 12588 final Iterator<PreferredActivity> it = pir.filterIterator(); 12589 while (it.hasNext()) { 12590 final PreferredActivity pa = it.next(); 12591 if (packageName == null 12592 || (pa.mPref.mComponent.getPackageName().equals(packageName) 12593 && pa.mPref.mAlways)) { 12594 if (outFilters != null) { 12595 outFilters.add(new IntentFilter(pa)); 12596 } 12597 if (outActivities != null) { 12598 outActivities.add(pa.mPref.mComponent); 12599 } 12600 } 12601 } 12602 } 12603 } 12604 12605 return num; 12606 } 12607 12608 @Override 12609 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 12610 int userId) { 12611 int callingUid = Binder.getCallingUid(); 12612 if (callingUid != Process.SYSTEM_UID) { 12613 throw new SecurityException( 12614 "addPersistentPreferredActivity can only be run by the system"); 12615 } 12616 if (filter.countActions() == 0) { 12617 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 12618 return; 12619 } 12620 synchronized (mPackages) { 12621 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 12622 " :"); 12623 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12624 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 12625 new PersistentPreferredActivity(filter, activity)); 12626 scheduleWritePackageRestrictionsLocked(userId); 12627 } 12628 } 12629 12630 @Override 12631 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 12632 int callingUid = Binder.getCallingUid(); 12633 if (callingUid != Process.SYSTEM_UID) { 12634 throw new SecurityException( 12635 "clearPackagePersistentPreferredActivities can only be run by the system"); 12636 } 12637 ArrayList<PersistentPreferredActivity> removed = null; 12638 boolean changed = false; 12639 synchronized (mPackages) { 12640 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 12641 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 12642 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 12643 .valueAt(i); 12644 if (userId != thisUserId) { 12645 continue; 12646 } 12647 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 12648 while (it.hasNext()) { 12649 PersistentPreferredActivity ppa = it.next(); 12650 // Mark entry for removal only if it matches the package name. 12651 if (ppa.mComponent.getPackageName().equals(packageName)) { 12652 if (removed == null) { 12653 removed = new ArrayList<PersistentPreferredActivity>(); 12654 } 12655 removed.add(ppa); 12656 } 12657 } 12658 if (removed != null) { 12659 for (int j=0; j<removed.size(); j++) { 12660 PersistentPreferredActivity ppa = removed.get(j); 12661 ppir.removeFilter(ppa); 12662 } 12663 changed = true; 12664 } 12665 } 12666 12667 if (changed) { 12668 scheduleWritePackageRestrictionsLocked(userId); 12669 } 12670 } 12671 } 12672 12673 /** 12674 * Non-Binder method, support for the backup/restore mechanism: write the 12675 * full set of preferred activities in its canonical XML format. Returns true 12676 * on success; false otherwise. 12677 */ 12678 @Override 12679 public byte[] getPreferredActivityBackup(int userId) { 12680 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12681 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 12682 } 12683 12684 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 12685 try { 12686 final XmlSerializer serializer = new FastXmlSerializer(); 12687 serializer.setOutput(dataStream, "utf-8"); 12688 serializer.startDocument(null, true); 12689 serializer.startTag(null, TAG_PREFERRED_BACKUP); 12690 12691 synchronized (mPackages) { 12692 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 12693 } 12694 12695 serializer.endTag(null, TAG_PREFERRED_BACKUP); 12696 serializer.endDocument(); 12697 serializer.flush(); 12698 } catch (Exception e) { 12699 if (DEBUG_BACKUP) { 12700 Slog.e(TAG, "Unable to write preferred activities for backup", e); 12701 } 12702 return null; 12703 } 12704 12705 return dataStream.toByteArray(); 12706 } 12707 12708 @Override 12709 public void restorePreferredActivities(byte[] backup, int userId) { 12710 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12711 throw new SecurityException("Only the system may call restorePreferredActivities()"); 12712 } 12713 12714 try { 12715 final XmlPullParser parser = Xml.newPullParser(); 12716 parser.setInput(new ByteArrayInputStream(backup), null); 12717 12718 int type; 12719 while ((type = parser.next()) != XmlPullParser.START_TAG 12720 && type != XmlPullParser.END_DOCUMENT) { 12721 } 12722 if (type != XmlPullParser.START_TAG) { 12723 // oops didn't find a start tag?! 12724 if (DEBUG_BACKUP) { 12725 Slog.e(TAG, "Didn't find start tag during restore"); 12726 } 12727 return; 12728 } 12729 12730 // this is supposed to be TAG_PREFERRED_BACKUP 12731 if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) { 12732 if (DEBUG_BACKUP) { 12733 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 12734 } 12735 return; 12736 } 12737 12738 // skip interfering stuff, then we're aligned with the backing implementation 12739 while ((type = parser.next()) == XmlPullParser.TEXT) { } 12740 synchronized (mPackages) { 12741 mSettings.readPreferredActivitiesLPw(parser, userId); 12742 } 12743 } catch (Exception e) { 12744 if (DEBUG_BACKUP) { 12745 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 12746 } 12747 } 12748 } 12749 12750 @Override 12751 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 12752 int sourceUserId, int targetUserId, int flags) { 12753 mContext.enforceCallingOrSelfPermission( 12754 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 12755 int callingUid = Binder.getCallingUid(); 12756 enforceOwnerRights(ownerPackage, callingUid); 12757 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 12758 if (intentFilter.countActions() == 0) { 12759 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 12760 return; 12761 } 12762 synchronized (mPackages) { 12763 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 12764 ownerPackage, targetUserId, flags); 12765 CrossProfileIntentResolver resolver = 12766 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 12767 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 12768 // We have all those whose filter is equal. Now checking if the rest is equal as well. 12769 if (existing != null) { 12770 int size = existing.size(); 12771 for (int i = 0; i < size; i++) { 12772 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 12773 return; 12774 } 12775 } 12776 } 12777 resolver.addFilter(newFilter); 12778 scheduleWritePackageRestrictionsLocked(sourceUserId); 12779 } 12780 } 12781 12782 @Override 12783 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 12784 mContext.enforceCallingOrSelfPermission( 12785 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 12786 int callingUid = Binder.getCallingUid(); 12787 enforceOwnerRights(ownerPackage, callingUid); 12788 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 12789 synchronized (mPackages) { 12790 CrossProfileIntentResolver resolver = 12791 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 12792 ArraySet<CrossProfileIntentFilter> set = 12793 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 12794 for (CrossProfileIntentFilter filter : set) { 12795 if (filter.getOwnerPackage().equals(ownerPackage)) { 12796 resolver.removeFilter(filter); 12797 } 12798 } 12799 scheduleWritePackageRestrictionsLocked(sourceUserId); 12800 } 12801 } 12802 12803 // Enforcing that callingUid is owning pkg on userId 12804 private void enforceOwnerRights(String pkg, int callingUid) { 12805 // The system owns everything. 12806 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 12807 return; 12808 } 12809 int callingUserId = UserHandle.getUserId(callingUid); 12810 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 12811 if (pi == null) { 12812 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 12813 + callingUserId); 12814 } 12815 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 12816 throw new SecurityException("Calling uid " + callingUid 12817 + " does not own package " + pkg); 12818 } 12819 } 12820 12821 @Override 12822 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 12823 Intent intent = new Intent(Intent.ACTION_MAIN); 12824 intent.addCategory(Intent.CATEGORY_HOME); 12825 12826 final int callingUserId = UserHandle.getCallingUserId(); 12827 List<ResolveInfo> list = queryIntentActivities(intent, null, 12828 PackageManager.GET_META_DATA, callingUserId); 12829 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 12830 true, false, false, callingUserId); 12831 12832 allHomeCandidates.clear(); 12833 if (list != null) { 12834 for (ResolveInfo ri : list) { 12835 allHomeCandidates.add(ri); 12836 } 12837 } 12838 return (preferred == null || preferred.activityInfo == null) 12839 ? null 12840 : new ComponentName(preferred.activityInfo.packageName, 12841 preferred.activityInfo.name); 12842 } 12843 12844 @Override 12845 public void setApplicationEnabledSetting(String appPackageName, 12846 int newState, int flags, int userId, String callingPackage) { 12847 if (!sUserManager.exists(userId)) return; 12848 if (callingPackage == null) { 12849 callingPackage = Integer.toString(Binder.getCallingUid()); 12850 } 12851 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 12852 } 12853 12854 @Override 12855 public void setComponentEnabledSetting(ComponentName componentName, 12856 int newState, int flags, int userId) { 12857 if (!sUserManager.exists(userId)) return; 12858 setEnabledSetting(componentName.getPackageName(), 12859 componentName.getClassName(), newState, flags, userId, null); 12860 } 12861 12862 private void setEnabledSetting(final String packageName, String className, int newState, 12863 final int flags, int userId, String callingPackage) { 12864 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 12865 || newState == COMPONENT_ENABLED_STATE_ENABLED 12866 || newState == COMPONENT_ENABLED_STATE_DISABLED 12867 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 12868 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 12869 throw new IllegalArgumentException("Invalid new component state: " 12870 + newState); 12871 } 12872 PackageSetting pkgSetting; 12873 final int uid = Binder.getCallingUid(); 12874 final int permission = mContext.checkCallingOrSelfPermission( 12875 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 12876 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 12877 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 12878 boolean sendNow = false; 12879 boolean isApp = (className == null); 12880 String componentName = isApp ? packageName : className; 12881 int packageUid = -1; 12882 ArrayList<String> components; 12883 12884 // writer 12885 synchronized (mPackages) { 12886 pkgSetting = mSettings.mPackages.get(packageName); 12887 if (pkgSetting == null) { 12888 if (className == null) { 12889 throw new IllegalArgumentException( 12890 "Unknown package: " + packageName); 12891 } 12892 throw new IllegalArgumentException( 12893 "Unknown component: " + packageName 12894 + "/" + className); 12895 } 12896 // Allow root and verify that userId is not being specified by a different user 12897 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 12898 throw new SecurityException( 12899 "Permission Denial: attempt to change component state from pid=" 12900 + Binder.getCallingPid() 12901 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 12902 } 12903 if (className == null) { 12904 // We're dealing with an application/package level state change 12905 if (pkgSetting.getEnabled(userId) == newState) { 12906 // Nothing to do 12907 return; 12908 } 12909 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 12910 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 12911 // Don't care about who enables an app. 12912 callingPackage = null; 12913 } 12914 pkgSetting.setEnabled(newState, userId, callingPackage); 12915 // pkgSetting.pkg.mSetEnabled = newState; 12916 } else { 12917 // We're dealing with a component level state change 12918 // First, verify that this is a valid class name. 12919 PackageParser.Package pkg = pkgSetting.pkg; 12920 if (pkg == null || !pkg.hasComponentClassName(className)) { 12921 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 12922 throw new IllegalArgumentException("Component class " + className 12923 + " does not exist in " + packageName); 12924 } else { 12925 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 12926 + className + " does not exist in " + packageName); 12927 } 12928 } 12929 switch (newState) { 12930 case COMPONENT_ENABLED_STATE_ENABLED: 12931 if (!pkgSetting.enableComponentLPw(className, userId)) { 12932 return; 12933 } 12934 break; 12935 case COMPONENT_ENABLED_STATE_DISABLED: 12936 if (!pkgSetting.disableComponentLPw(className, userId)) { 12937 return; 12938 } 12939 break; 12940 case COMPONENT_ENABLED_STATE_DEFAULT: 12941 if (!pkgSetting.restoreComponentLPw(className, userId)) { 12942 return; 12943 } 12944 break; 12945 default: 12946 Slog.e(TAG, "Invalid new component state: " + newState); 12947 return; 12948 } 12949 } 12950 scheduleWritePackageRestrictionsLocked(userId); 12951 components = mPendingBroadcasts.get(userId, packageName); 12952 final boolean newPackage = components == null; 12953 if (newPackage) { 12954 components = new ArrayList<String>(); 12955 } 12956 if (!components.contains(componentName)) { 12957 components.add(componentName); 12958 } 12959 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 12960 sendNow = true; 12961 // Purge entry from pending broadcast list if another one exists already 12962 // since we are sending one right away. 12963 mPendingBroadcasts.remove(userId, packageName); 12964 } else { 12965 if (newPackage) { 12966 mPendingBroadcasts.put(userId, packageName, components); 12967 } 12968 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 12969 // Schedule a message 12970 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 12971 } 12972 } 12973 } 12974 12975 long callingId = Binder.clearCallingIdentity(); 12976 try { 12977 if (sendNow) { 12978 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 12979 sendPackageChangedBroadcast(packageName, 12980 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 12981 } 12982 } finally { 12983 Binder.restoreCallingIdentity(callingId); 12984 } 12985 } 12986 12987 private void sendPackageChangedBroadcast(String packageName, 12988 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 12989 if (DEBUG_INSTALL) 12990 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 12991 + componentNames); 12992 Bundle extras = new Bundle(4); 12993 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 12994 String nameList[] = new String[componentNames.size()]; 12995 componentNames.toArray(nameList); 12996 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 12997 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 12998 extras.putInt(Intent.EXTRA_UID, packageUid); 12999 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 13000 new int[] {UserHandle.getUserId(packageUid)}); 13001 } 13002 13003 @Override 13004 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 13005 if (!sUserManager.exists(userId)) return; 13006 final int uid = Binder.getCallingUid(); 13007 final int permission = mContext.checkCallingOrSelfPermission( 13008 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 13009 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 13010 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 13011 // writer 13012 synchronized (mPackages) { 13013 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, 13014 uid, userId)) { 13015 scheduleWritePackageRestrictionsLocked(userId); 13016 } 13017 } 13018 } 13019 13020 @Override 13021 public String getInstallerPackageName(String packageName) { 13022 // reader 13023 synchronized (mPackages) { 13024 return mSettings.getInstallerPackageNameLPr(packageName); 13025 } 13026 } 13027 13028 @Override 13029 public int getApplicationEnabledSetting(String packageName, int userId) { 13030 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13031 int uid = Binder.getCallingUid(); 13032 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 13033 // reader 13034 synchronized (mPackages) { 13035 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 13036 } 13037 } 13038 13039 @Override 13040 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 13041 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13042 int uid = Binder.getCallingUid(); 13043 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 13044 // reader 13045 synchronized (mPackages) { 13046 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 13047 } 13048 } 13049 13050 @Override 13051 public void enterSafeMode() { 13052 enforceSystemOrRoot("Only the system can request entering safe mode"); 13053 13054 if (!mSystemReady) { 13055 mSafeMode = true; 13056 } 13057 } 13058 13059 @Override 13060 public void systemReady() { 13061 mSystemReady = true; 13062 13063 // Read the compatibilty setting when the system is ready. 13064 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 13065 mContext.getContentResolver(), 13066 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 13067 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 13068 if (DEBUG_SETTINGS) { 13069 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 13070 } 13071 13072 synchronized (mPackages) { 13073 // Verify that all of the preferred activity components actually 13074 // exist. It is possible for applications to be updated and at 13075 // that point remove a previously declared activity component that 13076 // had been set as a preferred activity. We try to clean this up 13077 // the next time we encounter that preferred activity, but it is 13078 // possible for the user flow to never be able to return to that 13079 // situation so here we do a sanity check to make sure we haven't 13080 // left any junk around. 13081 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 13082 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13083 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13084 removed.clear(); 13085 for (PreferredActivity pa : pir.filterSet()) { 13086 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 13087 removed.add(pa); 13088 } 13089 } 13090 if (removed.size() > 0) { 13091 for (int r=0; r<removed.size(); r++) { 13092 PreferredActivity pa = removed.get(r); 13093 Slog.w(TAG, "Removing dangling preferred activity: " 13094 + pa.mPref.mComponent); 13095 pir.removeFilter(pa); 13096 } 13097 mSettings.writePackageRestrictionsLPr( 13098 mSettings.mPreferredActivities.keyAt(i)); 13099 } 13100 } 13101 } 13102 sUserManager.systemReady(); 13103 13104 // Kick off any messages waiting for system ready 13105 if (mPostSystemReadyMessages != null) { 13106 for (Message msg : mPostSystemReadyMessages) { 13107 msg.sendToTarget(); 13108 } 13109 mPostSystemReadyMessages = null; 13110 } 13111 13112 // Watch for external volumes that come and go over time 13113 final StorageManager storage = mContext.getSystemService(StorageManager.class); 13114 storage.registerListener(mStorageListener); 13115 13116 mInstallerService.systemReady(); 13117 } 13118 13119 @Override 13120 public boolean isSafeMode() { 13121 return mSafeMode; 13122 } 13123 13124 @Override 13125 public boolean hasSystemUidErrors() { 13126 return mHasSystemUidErrors; 13127 } 13128 13129 static String arrayToString(int[] array) { 13130 StringBuffer buf = new StringBuffer(128); 13131 buf.append('['); 13132 if (array != null) { 13133 for (int i=0; i<array.length; i++) { 13134 if (i > 0) buf.append(", "); 13135 buf.append(array[i]); 13136 } 13137 } 13138 buf.append(']'); 13139 return buf.toString(); 13140 } 13141 13142 static class DumpState { 13143 public static final int DUMP_LIBS = 1 << 0; 13144 public static final int DUMP_FEATURES = 1 << 1; 13145 public static final int DUMP_RESOLVERS = 1 << 2; 13146 public static final int DUMP_PERMISSIONS = 1 << 3; 13147 public static final int DUMP_PACKAGES = 1 << 4; 13148 public static final int DUMP_SHARED_USERS = 1 << 5; 13149 public static final int DUMP_MESSAGES = 1 << 6; 13150 public static final int DUMP_PROVIDERS = 1 << 7; 13151 public static final int DUMP_VERIFIERS = 1 << 8; 13152 public static final int DUMP_PREFERRED = 1 << 9; 13153 public static final int DUMP_PREFERRED_XML = 1 << 10; 13154 public static final int DUMP_KEYSETS = 1 << 11; 13155 public static final int DUMP_VERSION = 1 << 12; 13156 public static final int DUMP_INSTALLS = 1 << 13; 13157 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14; 13158 public static final int DUMP_DOMAIN_PREFERRED = 1 << 15; 13159 13160 public static final int OPTION_SHOW_FILTERS = 1 << 0; 13161 13162 private int mTypes; 13163 13164 private int mOptions; 13165 13166 private boolean mTitlePrinted; 13167 13168 private SharedUserSetting mSharedUser; 13169 13170 public boolean isDumping(int type) { 13171 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 13172 return true; 13173 } 13174 13175 return (mTypes & type) != 0; 13176 } 13177 13178 public void setDump(int type) { 13179 mTypes |= type; 13180 } 13181 13182 public boolean isOptionEnabled(int option) { 13183 return (mOptions & option) != 0; 13184 } 13185 13186 public void setOptionEnabled(int option) { 13187 mOptions |= option; 13188 } 13189 13190 public boolean onTitlePrinted() { 13191 final boolean printed = mTitlePrinted; 13192 mTitlePrinted = true; 13193 return printed; 13194 } 13195 13196 public boolean getTitlePrinted() { 13197 return mTitlePrinted; 13198 } 13199 13200 public void setTitlePrinted(boolean enabled) { 13201 mTitlePrinted = enabled; 13202 } 13203 13204 public SharedUserSetting getSharedUser() { 13205 return mSharedUser; 13206 } 13207 13208 public void setSharedUser(SharedUserSetting user) { 13209 mSharedUser = user; 13210 } 13211 } 13212 13213 @Override 13214 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 13215 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 13216 != PackageManager.PERMISSION_GRANTED) { 13217 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 13218 + Binder.getCallingPid() 13219 + ", uid=" + Binder.getCallingUid() 13220 + " without permission " 13221 + android.Manifest.permission.DUMP); 13222 return; 13223 } 13224 13225 DumpState dumpState = new DumpState(); 13226 boolean fullPreferred = false; 13227 boolean checkin = false; 13228 13229 String packageName = null; 13230 13231 int opti = 0; 13232 while (opti < args.length) { 13233 String opt = args[opti]; 13234 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13235 break; 13236 } 13237 opti++; 13238 13239 if ("-a".equals(opt)) { 13240 // Right now we only know how to print all. 13241 } else if ("-h".equals(opt)) { 13242 pw.println("Package manager dump options:"); 13243 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 13244 pw.println(" --checkin: dump for a checkin"); 13245 pw.println(" -f: print details of intent filters"); 13246 pw.println(" -h: print this help"); 13247 pw.println(" cmd may be one of:"); 13248 pw.println(" l[ibraries]: list known shared libraries"); 13249 pw.println(" f[ibraries]: list device features"); 13250 pw.println(" k[eysets]: print known keysets"); 13251 pw.println(" r[esolvers]: dump intent resolvers"); 13252 pw.println(" perm[issions]: dump permissions"); 13253 pw.println(" pref[erred]: print preferred package settings"); 13254 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 13255 pw.println(" prov[iders]: dump content providers"); 13256 pw.println(" p[ackages]: dump installed packages"); 13257 pw.println(" s[hared-users]: dump shared user IDs"); 13258 pw.println(" m[essages]: print collected runtime messages"); 13259 pw.println(" v[erifiers]: print package verifier info"); 13260 pw.println(" version: print database version info"); 13261 pw.println(" write: write current settings now"); 13262 pw.println(" <package.name>: info about given package"); 13263 pw.println(" installs: details about install sessions"); 13264 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 13265 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 13266 return; 13267 } else if ("--checkin".equals(opt)) { 13268 checkin = true; 13269 } else if ("-f".equals(opt)) { 13270 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13271 } else { 13272 pw.println("Unknown argument: " + opt + "; use -h for help"); 13273 } 13274 } 13275 13276 // Is the caller requesting to dump a particular piece of data? 13277 if (opti < args.length) { 13278 String cmd = args[opti]; 13279 opti++; 13280 // Is this a package name? 13281 if ("android".equals(cmd) || cmd.contains(".")) { 13282 packageName = cmd; 13283 // When dumping a single package, we always dump all of its 13284 // filter information since the amount of data will be reasonable. 13285 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13286 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 13287 dumpState.setDump(DumpState.DUMP_LIBS); 13288 } else if ("f".equals(cmd) || "features".equals(cmd)) { 13289 dumpState.setDump(DumpState.DUMP_FEATURES); 13290 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 13291 dumpState.setDump(DumpState.DUMP_RESOLVERS); 13292 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 13293 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 13294 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 13295 dumpState.setDump(DumpState.DUMP_PREFERRED); 13296 } else if ("preferred-xml".equals(cmd)) { 13297 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 13298 if (opti < args.length && "--full".equals(args[opti])) { 13299 fullPreferred = true; 13300 opti++; 13301 } 13302 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 13303 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 13304 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 13305 dumpState.setDump(DumpState.DUMP_PACKAGES); 13306 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 13307 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 13308 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 13309 dumpState.setDump(DumpState.DUMP_PROVIDERS); 13310 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 13311 dumpState.setDump(DumpState.DUMP_MESSAGES); 13312 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 13313 dumpState.setDump(DumpState.DUMP_VERIFIERS); 13314 } else if ("i".equals(cmd) || "ifv".equals(cmd) 13315 || "intent-filter-verifiers".equals(cmd)) { 13316 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 13317 } else if ("version".equals(cmd)) { 13318 dumpState.setDump(DumpState.DUMP_VERSION); 13319 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 13320 dumpState.setDump(DumpState.DUMP_KEYSETS); 13321 } else if ("installs".equals(cmd)) { 13322 dumpState.setDump(DumpState.DUMP_INSTALLS); 13323 } else if ("write".equals(cmd)) { 13324 synchronized (mPackages) { 13325 mSettings.writeLPr(); 13326 pw.println("Settings written."); 13327 return; 13328 } 13329 } 13330 } 13331 13332 if (checkin) { 13333 pw.println("vers,1"); 13334 } 13335 13336 // reader 13337 synchronized (mPackages) { 13338 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 13339 if (!checkin) { 13340 if (dumpState.onTitlePrinted()) 13341 pw.println(); 13342 pw.println("Database versions:"); 13343 pw.print(" SDK Version:"); 13344 pw.print(" internal="); 13345 pw.print(mSettings.mInternalSdkPlatform); 13346 pw.print(" external="); 13347 pw.println(mSettings.mExternalSdkPlatform); 13348 pw.print(" DB Version:"); 13349 pw.print(" internal="); 13350 pw.print(mSettings.mInternalDatabaseVersion); 13351 pw.print(" external="); 13352 pw.println(mSettings.mExternalDatabaseVersion); 13353 } 13354 } 13355 13356 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 13357 if (!checkin) { 13358 if (dumpState.onTitlePrinted()) 13359 pw.println(); 13360 pw.println("Verifiers:"); 13361 pw.print(" Required: "); 13362 pw.print(mRequiredVerifierPackage); 13363 pw.print(" (uid="); 13364 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 13365 pw.println(")"); 13366 } else if (mRequiredVerifierPackage != null) { 13367 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 13368 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 13369 } 13370 } 13371 13372 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 13373 packageName == null) { 13374 if (mIntentFilterVerifierComponent != null) { 13375 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 13376 if (!checkin) { 13377 if (dumpState.onTitlePrinted()) 13378 pw.println(); 13379 pw.println("Intent Filter Verifier:"); 13380 pw.print(" Using: "); 13381 pw.print(verifierPackageName); 13382 pw.print(" (uid="); 13383 pw.print(getPackageUid(verifierPackageName, 0)); 13384 pw.println(")"); 13385 } else if (verifierPackageName != null) { 13386 pw.print("ifv,"); pw.print(verifierPackageName); 13387 pw.print(","); pw.println(getPackageUid(verifierPackageName, 0)); 13388 } 13389 } else { 13390 pw.println(); 13391 pw.println("No Intent Filter Verifier available!"); 13392 } 13393 } 13394 13395 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 13396 boolean printedHeader = false; 13397 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 13398 while (it.hasNext()) { 13399 String name = it.next(); 13400 SharedLibraryEntry ent = mSharedLibraries.get(name); 13401 if (!checkin) { 13402 if (!printedHeader) { 13403 if (dumpState.onTitlePrinted()) 13404 pw.println(); 13405 pw.println("Libraries:"); 13406 printedHeader = true; 13407 } 13408 pw.print(" "); 13409 } else { 13410 pw.print("lib,"); 13411 } 13412 pw.print(name); 13413 if (!checkin) { 13414 pw.print(" -> "); 13415 } 13416 if (ent.path != null) { 13417 if (!checkin) { 13418 pw.print("(jar) "); 13419 pw.print(ent.path); 13420 } else { 13421 pw.print(",jar,"); 13422 pw.print(ent.path); 13423 } 13424 } else { 13425 if (!checkin) { 13426 pw.print("(apk) "); 13427 pw.print(ent.apk); 13428 } else { 13429 pw.print(",apk,"); 13430 pw.print(ent.apk); 13431 } 13432 } 13433 pw.println(); 13434 } 13435 } 13436 13437 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 13438 if (dumpState.onTitlePrinted()) 13439 pw.println(); 13440 if (!checkin) { 13441 pw.println("Features:"); 13442 } 13443 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 13444 while (it.hasNext()) { 13445 String name = it.next(); 13446 if (!checkin) { 13447 pw.print(" "); 13448 } else { 13449 pw.print("feat,"); 13450 } 13451 pw.println(name); 13452 } 13453 } 13454 13455 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 13456 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 13457 : "Activity Resolver Table:", " ", packageName, 13458 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13459 dumpState.setTitlePrinted(true); 13460 } 13461 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 13462 : "Receiver Resolver Table:", " ", packageName, 13463 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13464 dumpState.setTitlePrinted(true); 13465 } 13466 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 13467 : "Service Resolver Table:", " ", packageName, 13468 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13469 dumpState.setTitlePrinted(true); 13470 } 13471 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 13472 : "Provider Resolver Table:", " ", packageName, 13473 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13474 dumpState.setTitlePrinted(true); 13475 } 13476 } 13477 13478 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 13479 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13480 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13481 int user = mSettings.mPreferredActivities.keyAt(i); 13482 if (pir.dump(pw, 13483 dumpState.getTitlePrinted() 13484 ? "\nPreferred Activities User " + user + ":" 13485 : "Preferred Activities User " + user + ":", " ", 13486 packageName, true, false)) { 13487 dumpState.setTitlePrinted(true); 13488 } 13489 } 13490 } 13491 13492 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 13493 pw.flush(); 13494 FileOutputStream fout = new FileOutputStream(fd); 13495 BufferedOutputStream str = new BufferedOutputStream(fout); 13496 XmlSerializer serializer = new FastXmlSerializer(); 13497 try { 13498 serializer.setOutput(str, "utf-8"); 13499 serializer.startDocument(null, true); 13500 serializer.setFeature( 13501 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 13502 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 13503 serializer.endDocument(); 13504 serializer.flush(); 13505 } catch (IllegalArgumentException e) { 13506 pw.println("Failed writing: " + e); 13507 } catch (IllegalStateException e) { 13508 pw.println("Failed writing: " + e); 13509 } catch (IOException e) { 13510 pw.println("Failed writing: " + e); 13511 } 13512 } 13513 13514 if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) { 13515 pw.println(); 13516 int count = mSettings.mPackages.size(); 13517 if (count == 0) { 13518 pw.println("No domain preferred apps!"); 13519 pw.println(); 13520 } else { 13521 final String prefix = " "; 13522 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 13523 if (allPackageSettings.size() == 0) { 13524 pw.println("No domain preferred apps!"); 13525 pw.println(); 13526 } else { 13527 pw.println("Domain preferred apps status:"); 13528 pw.println(); 13529 count = 0; 13530 for (PackageSetting ps : allPackageSettings) { 13531 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 13532 if (ivi == null || ivi.getPackageName() == null) continue; 13533 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 13534 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 13535 pw.println(prefix + "Status: " + ivi.getStatusString()); 13536 pw.println(); 13537 count++; 13538 } 13539 if (count == 0) { 13540 pw.println(prefix + "No domain preferred app status!"); 13541 pw.println(); 13542 } 13543 for (int userId : sUserManager.getUserIds()) { 13544 pw.println("Domain preferred apps for User " + userId + ":"); 13545 pw.println(); 13546 count = 0; 13547 for (PackageSetting ps : allPackageSettings) { 13548 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 13549 if (ivi == null || ivi.getPackageName() == null) { 13550 continue; 13551 } 13552 final int status = ps.getDomainVerificationStatusForUser(userId); 13553 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 13554 continue; 13555 } 13556 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 13557 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 13558 String statusStr = IntentFilterVerificationInfo. 13559 getStatusStringFromValue(status); 13560 pw.println(prefix + "Status: " + statusStr); 13561 pw.println(); 13562 count++; 13563 } 13564 if (count == 0) { 13565 pw.println(prefix + "No domain preferred apps!"); 13566 pw.println(); 13567 } 13568 } 13569 } 13570 } 13571 } 13572 13573 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 13574 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 13575 if (packageName == null) { 13576 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 13577 if (iperm == 0) { 13578 if (dumpState.onTitlePrinted()) 13579 pw.println(); 13580 pw.println("AppOp Permissions:"); 13581 } 13582 pw.print(" AppOp Permission "); 13583 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 13584 pw.println(":"); 13585 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 13586 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 13587 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 13588 } 13589 } 13590 } 13591 } 13592 13593 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 13594 boolean printedSomething = false; 13595 for (PackageParser.Provider p : mProviders.mProviders.values()) { 13596 if (packageName != null && !packageName.equals(p.info.packageName)) { 13597 continue; 13598 } 13599 if (!printedSomething) { 13600 if (dumpState.onTitlePrinted()) 13601 pw.println(); 13602 pw.println("Registered ContentProviders:"); 13603 printedSomething = true; 13604 } 13605 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 13606 pw.print(" "); pw.println(p.toString()); 13607 } 13608 printedSomething = false; 13609 for (Map.Entry<String, PackageParser.Provider> entry : 13610 mProvidersByAuthority.entrySet()) { 13611 PackageParser.Provider p = entry.getValue(); 13612 if (packageName != null && !packageName.equals(p.info.packageName)) { 13613 continue; 13614 } 13615 if (!printedSomething) { 13616 if (dumpState.onTitlePrinted()) 13617 pw.println(); 13618 pw.println("ContentProvider Authorities:"); 13619 printedSomething = true; 13620 } 13621 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 13622 pw.print(" "); pw.println(p.toString()); 13623 if (p.info != null && p.info.applicationInfo != null) { 13624 final String appInfo = p.info.applicationInfo.toString(); 13625 pw.print(" applicationInfo="); pw.println(appInfo); 13626 } 13627 } 13628 } 13629 13630 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 13631 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 13632 } 13633 13634 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 13635 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 13636 } 13637 13638 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 13639 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin); 13640 } 13641 13642 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 13643 // XXX should handle packageName != null by dumping only install data that 13644 // the given package is involved with. 13645 if (dumpState.onTitlePrinted()) pw.println(); 13646 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 13647 } 13648 13649 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 13650 if (dumpState.onTitlePrinted()) pw.println(); 13651 mSettings.dumpReadMessagesLPr(pw, dumpState); 13652 13653 pw.println(); 13654 pw.println("Package warning messages:"); 13655 BufferedReader in = null; 13656 String line = null; 13657 try { 13658 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 13659 while ((line = in.readLine()) != null) { 13660 if (line.contains("ignored: updated version")) continue; 13661 pw.println(line); 13662 } 13663 } catch (IOException ignored) { 13664 } finally { 13665 IoUtils.closeQuietly(in); 13666 } 13667 } 13668 13669 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 13670 BufferedReader in = null; 13671 String line = null; 13672 try { 13673 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 13674 while ((line = in.readLine()) != null) { 13675 if (line.contains("ignored: updated version")) continue; 13676 pw.print("msg,"); 13677 pw.println(line); 13678 } 13679 } catch (IOException ignored) { 13680 } finally { 13681 IoUtils.closeQuietly(in); 13682 } 13683 } 13684 } 13685 } 13686 13687 // ------- apps on sdcard specific code ------- 13688 static final boolean DEBUG_SD_INSTALL = false; 13689 13690 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 13691 13692 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 13693 13694 private boolean mMediaMounted = false; 13695 13696 static String getEncryptKey() { 13697 try { 13698 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 13699 SD_ENCRYPTION_KEYSTORE_NAME); 13700 if (sdEncKey == null) { 13701 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 13702 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 13703 if (sdEncKey == null) { 13704 Slog.e(TAG, "Failed to create encryption keys"); 13705 return null; 13706 } 13707 } 13708 return sdEncKey; 13709 } catch (NoSuchAlgorithmException nsae) { 13710 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 13711 return null; 13712 } catch (IOException ioe) { 13713 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 13714 return null; 13715 } 13716 } 13717 13718 /* 13719 * Update media status on PackageManager. 13720 */ 13721 @Override 13722 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 13723 int callingUid = Binder.getCallingUid(); 13724 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13725 throw new SecurityException("Media status can only be updated by the system"); 13726 } 13727 // reader; this apparently protects mMediaMounted, but should probably 13728 // be a different lock in that case. 13729 synchronized (mPackages) { 13730 Log.i(TAG, "Updating external media status from " 13731 + (mMediaMounted ? "mounted" : "unmounted") + " to " 13732 + (mediaStatus ? "mounted" : "unmounted")); 13733 if (DEBUG_SD_INSTALL) 13734 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 13735 + ", mMediaMounted=" + mMediaMounted); 13736 if (mediaStatus == mMediaMounted) { 13737 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 13738 : 0, -1); 13739 mHandler.sendMessage(msg); 13740 return; 13741 } 13742 mMediaMounted = mediaStatus; 13743 } 13744 // Queue up an async operation since the package installation may take a 13745 // little while. 13746 mHandler.post(new Runnable() { 13747 public void run() { 13748 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 13749 } 13750 }); 13751 } 13752 13753 /** 13754 * Called by MountService when the initial ASECs to scan are available. 13755 * Should block until all the ASEC containers are finished being scanned. 13756 */ 13757 public void scanAvailableAsecs() { 13758 updateExternalMediaStatusInner(true, false, false); 13759 if (mShouldRestoreconData) { 13760 SELinuxMMAC.setRestoreconDone(); 13761 mShouldRestoreconData = false; 13762 } 13763 } 13764 13765 /* 13766 * Collect information of applications on external media, map them against 13767 * existing containers and update information based on current mount status. 13768 * Please note that we always have to report status if reportStatus has been 13769 * set to true especially when unloading packages. 13770 */ 13771 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 13772 boolean externalStorage) { 13773 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 13774 int[] uidArr = EmptyArray.INT; 13775 13776 final String[] list = PackageHelper.getSecureContainerList(); 13777 if (ArrayUtils.isEmpty(list)) { 13778 Log.i(TAG, "No secure containers found"); 13779 } else { 13780 // Process list of secure containers and categorize them 13781 // as active or stale based on their package internal state. 13782 13783 // reader 13784 synchronized (mPackages) { 13785 for (String cid : list) { 13786 // Leave stages untouched for now; installer service owns them 13787 if (PackageInstallerService.isStageName(cid)) continue; 13788 13789 if (DEBUG_SD_INSTALL) 13790 Log.i(TAG, "Processing container " + cid); 13791 String pkgName = getAsecPackageName(cid); 13792 if (pkgName == null) { 13793 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 13794 continue; 13795 } 13796 if (DEBUG_SD_INSTALL) 13797 Log.i(TAG, "Looking for pkg : " + pkgName); 13798 13799 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13800 if (ps == null) { 13801 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 13802 continue; 13803 } 13804 13805 /* 13806 * Skip packages that are not external if we're unmounting 13807 * external storage. 13808 */ 13809 if (externalStorage && !isMounted && !isExternal(ps)) { 13810 continue; 13811 } 13812 13813 final AsecInstallArgs args = new AsecInstallArgs(cid, 13814 getAppDexInstructionSets(ps), ps.isForwardLocked()); 13815 // The package status is changed only if the code path 13816 // matches between settings and the container id. 13817 if (ps.codePathString != null 13818 && ps.codePathString.startsWith(args.getCodePath())) { 13819 if (DEBUG_SD_INSTALL) { 13820 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 13821 + " at code path: " + ps.codePathString); 13822 } 13823 13824 // We do have a valid package installed on sdcard 13825 processCids.put(args, ps.codePathString); 13826 final int uid = ps.appId; 13827 if (uid != -1) { 13828 uidArr = ArrayUtils.appendInt(uidArr, uid); 13829 } 13830 } else { 13831 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 13832 + ps.codePathString); 13833 } 13834 } 13835 } 13836 13837 Arrays.sort(uidArr); 13838 } 13839 13840 // Process packages with valid entries. 13841 if (isMounted) { 13842 if (DEBUG_SD_INSTALL) 13843 Log.i(TAG, "Loading packages"); 13844 loadMediaPackages(processCids, uidArr); 13845 startCleaningPackages(); 13846 mInstallerService.onSecureContainersAvailable(); 13847 } else { 13848 if (DEBUG_SD_INSTALL) 13849 Log.i(TAG, "Unloading packages"); 13850 unloadMediaPackages(processCids, uidArr, reportStatus); 13851 } 13852 } 13853 13854 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 13855 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 13856 final int size = infos.size(); 13857 final String[] packageNames = new String[size]; 13858 final int[] packageUids = new int[size]; 13859 for (int i = 0; i < size; i++) { 13860 final ApplicationInfo info = infos.get(i); 13861 packageNames[i] = info.packageName; 13862 packageUids[i] = info.uid; 13863 } 13864 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 13865 finishedReceiver); 13866 } 13867 13868 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 13869 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 13870 sendResourcesChangedBroadcast(mediaStatus, replacing, 13871 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 13872 } 13873 13874 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 13875 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 13876 int size = pkgList.length; 13877 if (size > 0) { 13878 // Send broadcasts here 13879 Bundle extras = new Bundle(); 13880 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 13881 if (uidArr != null) { 13882 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 13883 } 13884 if (replacing) { 13885 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 13886 } 13887 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 13888 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 13889 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 13890 } 13891 } 13892 13893 /* 13894 * Look at potentially valid container ids from processCids If package 13895 * information doesn't match the one on record or package scanning fails, 13896 * the cid is added to list of removeCids. We currently don't delete stale 13897 * containers. 13898 */ 13899 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) { 13900 ArrayList<String> pkgList = new ArrayList<String>(); 13901 Set<AsecInstallArgs> keys = processCids.keySet(); 13902 13903 for (AsecInstallArgs args : keys) { 13904 String codePath = processCids.get(args); 13905 if (DEBUG_SD_INSTALL) 13906 Log.i(TAG, "Loading container : " + args.cid); 13907 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13908 try { 13909 // Make sure there are no container errors first. 13910 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 13911 Slog.e(TAG, "Failed to mount cid : " + args.cid 13912 + " when installing from sdcard"); 13913 continue; 13914 } 13915 // Check code path here. 13916 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 13917 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 13918 + " does not match one in settings " + codePath); 13919 continue; 13920 } 13921 // Parse package 13922 int parseFlags = mDefParseFlags; 13923 if (args.isExternalAsec()) { 13924 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 13925 } 13926 if (args.isFwdLocked()) { 13927 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 13928 } 13929 13930 synchronized (mInstallLock) { 13931 PackageParser.Package pkg = null; 13932 try { 13933 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null); 13934 } catch (PackageManagerException e) { 13935 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 13936 } 13937 // Scan the package 13938 if (pkg != null) { 13939 /* 13940 * TODO why is the lock being held? doPostInstall is 13941 * called in other places without the lock. This needs 13942 * to be straightened out. 13943 */ 13944 // writer 13945 synchronized (mPackages) { 13946 retCode = PackageManager.INSTALL_SUCCEEDED; 13947 pkgList.add(pkg.packageName); 13948 // Post process args 13949 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 13950 pkg.applicationInfo.uid); 13951 } 13952 } else { 13953 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 13954 } 13955 } 13956 13957 } finally { 13958 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 13959 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 13960 } 13961 } 13962 } 13963 // writer 13964 synchronized (mPackages) { 13965 // If the platform SDK has changed since the last time we booted, 13966 // we need to re-grant app permission to catch any new ones that 13967 // appear. This is really a hack, and means that apps can in some 13968 // cases get permissions that the user didn't initially explicitly 13969 // allow... it would be nice to have some better way to handle 13970 // this situation. 13971 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 13972 if (regrantPermissions) 13973 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 13974 + mSdkVersion + "; regranting permissions for external storage"); 13975 mSettings.mExternalSdkPlatform = mSdkVersion; 13976 13977 // Make sure group IDs have been assigned, and any permission 13978 // changes in other apps are accounted for 13979 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 13980 | (regrantPermissions 13981 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 13982 : 0)); 13983 13984 mSettings.updateExternalDatabaseVersion(); 13985 13986 // can downgrade to reader 13987 // Persist settings 13988 mSettings.writeLPr(); 13989 } 13990 // Send a broadcast to let everyone know we are done processing 13991 if (pkgList.size() > 0) { 13992 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 13993 } 13994 } 13995 13996 /* 13997 * Utility method to unload a list of specified containers 13998 */ 13999 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 14000 // Just unmount all valid containers. 14001 for (AsecInstallArgs arg : cidArgs) { 14002 synchronized (mInstallLock) { 14003 arg.doPostDeleteLI(false); 14004 } 14005 } 14006 } 14007 14008 /* 14009 * Unload packages mounted on external media. This involves deleting package 14010 * data from internal structures, sending broadcasts about diabled packages, 14011 * gc'ing to free up references, unmounting all secure containers 14012 * corresponding to packages on external media, and posting a 14013 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 14014 * that we always have to post this message if status has been requested no 14015 * matter what. 14016 */ 14017 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 14018 final boolean reportStatus) { 14019 if (DEBUG_SD_INSTALL) 14020 Log.i(TAG, "unloading media packages"); 14021 ArrayList<String> pkgList = new ArrayList<String>(); 14022 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 14023 final Set<AsecInstallArgs> keys = processCids.keySet(); 14024 for (AsecInstallArgs args : keys) { 14025 String pkgName = args.getPackageName(); 14026 if (DEBUG_SD_INSTALL) 14027 Log.i(TAG, "Trying to unload pkg : " + pkgName); 14028 // Delete package internally 14029 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14030 synchronized (mInstallLock) { 14031 boolean res = deletePackageLI(pkgName, null, false, null, null, 14032 PackageManager.DELETE_KEEP_DATA, outInfo, false); 14033 if (res) { 14034 pkgList.add(pkgName); 14035 } else { 14036 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 14037 failedList.add(args); 14038 } 14039 } 14040 } 14041 14042 // reader 14043 synchronized (mPackages) { 14044 // We didn't update the settings after removing each package; 14045 // write them now for all packages. 14046 mSettings.writeLPr(); 14047 } 14048 14049 // We have to absolutely send UPDATED_MEDIA_STATUS only 14050 // after confirming that all the receivers processed the ordered 14051 // broadcast when packages get disabled, force a gc to clean things up. 14052 // and unload all the containers. 14053 if (pkgList.size() > 0) { 14054 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 14055 new IIntentReceiver.Stub() { 14056 public void performReceive(Intent intent, int resultCode, String data, 14057 Bundle extras, boolean ordered, boolean sticky, 14058 int sendingUser) throws RemoteException { 14059 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 14060 reportStatus ? 1 : 0, 1, keys); 14061 mHandler.sendMessage(msg); 14062 } 14063 }); 14064 } else { 14065 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 14066 keys); 14067 mHandler.sendMessage(msg); 14068 } 14069 } 14070 14071 private void loadPrivatePackages(VolumeInfo vol) { 14072 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 14073 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 14074 synchronized (mPackages) { 14075 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14076 for (PackageSetting ps : packages) { 14077 synchronized (mInstallLock) { 14078 final PackageParser.Package pkg; 14079 try { 14080 pkg = scanPackageLI(ps.codePath, parseFlags, 0, 0, null); 14081 loaded.add(pkg.applicationInfo); 14082 } catch (PackageManagerException e) { 14083 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 14084 } 14085 } 14086 } 14087 14088 // TODO: regrant any permissions that changed based since original install 14089 14090 mSettings.writeLPr(); 14091 } 14092 14093 Slog.d(TAG, "Loaded packages " + loaded); 14094 sendResourcesChangedBroadcast(true, false, loaded, null); 14095 } 14096 14097 private void unloadPrivatePackages(VolumeInfo vol) { 14098 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 14099 synchronized (mPackages) { 14100 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14101 for (PackageSetting ps : packages) { 14102 if (ps.pkg == null) continue; 14103 synchronized (mInstallLock) { 14104 final ApplicationInfo info = ps.pkg.applicationInfo; 14105 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14106 if (deletePackageLI(ps.name, null, false, null, null, 14107 PackageManager.DELETE_KEEP_DATA, outInfo, false)) { 14108 unloaded.add(info); 14109 } else { 14110 Slog.w(TAG, "Failed to unload " + ps.codePath); 14111 } 14112 } 14113 } 14114 14115 mSettings.writeLPr(); 14116 } 14117 14118 Slog.d(TAG, "Unloaded packages " + unloaded); 14119 sendResourcesChangedBroadcast(false, false, unloaded, null); 14120 } 14121 14122 @Override 14123 public void movePackage(final String packageName, final IPackageMoveObserver observer, 14124 final int flags) { 14125 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14126 14127 final int installFlags; 14128 if ((flags & MOVE_INTERNAL) != 0) { 14129 installFlags = INSTALL_INTERNAL; 14130 } else if ((flags & MOVE_EXTERNAL_MEDIA) != 0) { 14131 installFlags = INSTALL_EXTERNAL; 14132 } else { 14133 throw new IllegalArgumentException("Unsupported move flags " + flags); 14134 } 14135 14136 try { 14137 movePackageInternal(packageName, null, installFlags, false, observer); 14138 } catch (PackageManagerException e) { 14139 Slog.d(TAG, "Failed to move " + packageName, e); 14140 try { 14141 observer.packageMoved(packageName, e.error); 14142 } catch (RemoteException ignored) { 14143 } 14144 } 14145 } 14146 14147 @Override 14148 public void movePackageAndData(final String packageName, final String volumeUuid, 14149 final IPackageMoveObserver observer) { 14150 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14151 try { 14152 movePackageInternal(packageName, volumeUuid, INSTALL_INTERNAL, true, observer); 14153 } catch (PackageManagerException e) { 14154 Slog.d(TAG, "Failed to move " + packageName, e); 14155 try { 14156 observer.packageMoved(packageName, e.error); 14157 } catch (RemoteException ignored) { 14158 } 14159 } 14160 } 14161 14162 private void movePackageInternal(final String packageName, String volumeUuid, int installFlags, 14163 boolean andData, final IPackageMoveObserver observer) throws PackageManagerException { 14164 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 14165 14166 File codeFile = null; 14167 String installerPackageName = null; 14168 String packageAbiOverride = null; 14169 14170 // TOOD: move app private data before installing 14171 14172 // reader 14173 synchronized (mPackages) { 14174 final PackageParser.Package pkg = mPackages.get(packageName); 14175 final PackageSetting ps = mSettings.mPackages.get(packageName); 14176 if (pkg == null || ps == null) { 14177 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 14178 } 14179 14180 if (pkg.applicationInfo.isSystemApp()) { 14181 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 14182 "Cannot move system application"); 14183 } else if (pkg.mOperationPending) { 14184 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 14185 "Attempt to move package which has pending operations"); 14186 } 14187 14188 // TODO: yell if already in desired location 14189 14190 pkg.mOperationPending = true; 14191 14192 codeFile = new File(pkg.codePath); 14193 installerPackageName = ps.installerPackageName; 14194 packageAbiOverride = ps.cpuAbiOverrideString; 14195 } 14196 14197 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 14198 @Override 14199 public void onUserActionRequired(Intent intent) throws RemoteException { 14200 throw new IllegalStateException(); 14201 } 14202 14203 @Override 14204 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 14205 Bundle extras) throws RemoteException { 14206 Slog.d(TAG, "Install result for move: " 14207 + PackageManager.installStatusToString(returnCode, msg)); 14208 14209 // We usually have a new package now after the install, but if 14210 // we failed we need to clear the pending flag on the original 14211 // package object. 14212 synchronized (mPackages) { 14213 final PackageParser.Package pkg = mPackages.get(packageName); 14214 if (pkg != null) { 14215 pkg.mOperationPending = false; 14216 } 14217 } 14218 14219 final int status = PackageManager.installStatusToPublicStatus(returnCode); 14220 switch (status) { 14221 case PackageInstaller.STATUS_SUCCESS: 14222 observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED); 14223 break; 14224 case PackageInstaller.STATUS_FAILURE_STORAGE: 14225 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 14226 break; 14227 default: 14228 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR); 14229 break; 14230 } 14231 } 14232 }; 14233 14234 // Treat a move like reinstalling an existing app, which ensures that we 14235 // process everythign uniformly, like unpacking native libraries. 14236 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 14237 14238 final Message msg = mHandler.obtainMessage(INIT_COPY); 14239 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 14240 msg.obj = new InstallParams(origin, installObserver, installFlags, 14241 installerPackageName, volumeUuid, null, user, packageAbiOverride); 14242 mHandler.sendMessage(msg); 14243 } 14244 14245 @Override 14246 public boolean setInstallLocation(int loc) { 14247 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 14248 null); 14249 if (getInstallLocation() == loc) { 14250 return true; 14251 } 14252 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 14253 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 14254 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 14255 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 14256 return true; 14257 } 14258 return false; 14259 } 14260 14261 @Override 14262 public int getInstallLocation() { 14263 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 14264 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 14265 PackageHelper.APP_INSTALL_AUTO); 14266 } 14267 14268 /** Called by UserManagerService */ 14269 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 14270 mDirtyUsers.remove(userHandle); 14271 mSettings.removeUserLPw(userHandle); 14272 mPendingBroadcasts.remove(userHandle); 14273 if (mInstaller != null) { 14274 // Technically, we shouldn't be doing this with the package lock 14275 // held. However, this is very rare, and there is already so much 14276 // other disk I/O going on, that we'll let it slide for now. 14277 mInstaller.removeUserDataDirs(userHandle); 14278 } 14279 mUserNeedsBadging.delete(userHandle); 14280 removeUnusedPackagesLILPw(userManager, userHandle); 14281 } 14282 14283 /** 14284 * We're removing userHandle and would like to remove any downloaded packages 14285 * that are no longer in use by any other user. 14286 * @param userHandle the user being removed 14287 */ 14288 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 14289 final boolean DEBUG_CLEAN_APKS = false; 14290 int [] users = userManager.getUserIdsLPr(); 14291 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 14292 while (psit.hasNext()) { 14293 PackageSetting ps = psit.next(); 14294 if (ps.pkg == null) { 14295 continue; 14296 } 14297 final String packageName = ps.pkg.packageName; 14298 // Skip over if system app 14299 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14300 continue; 14301 } 14302 if (DEBUG_CLEAN_APKS) { 14303 Slog.i(TAG, "Checking package " + packageName); 14304 } 14305 boolean keep = false; 14306 for (int i = 0; i < users.length; i++) { 14307 if (users[i] != userHandle && ps.getInstalled(users[i])) { 14308 keep = true; 14309 if (DEBUG_CLEAN_APKS) { 14310 Slog.i(TAG, " Keeping package " + packageName + " for user " 14311 + users[i]); 14312 } 14313 break; 14314 } 14315 } 14316 if (!keep) { 14317 if (DEBUG_CLEAN_APKS) { 14318 Slog.i(TAG, " Removing package " + packageName); 14319 } 14320 mHandler.post(new Runnable() { 14321 public void run() { 14322 deletePackageX(packageName, userHandle, 0); 14323 } //end run 14324 }); 14325 } 14326 } 14327 } 14328 14329 /** Called by UserManagerService */ 14330 void createNewUserLILPw(int userHandle, File path) { 14331 if (mInstaller != null) { 14332 mInstaller.createUserConfig(userHandle); 14333 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 14334 } 14335 } 14336 14337 void newUserCreatedLILPw(int userHandle) { 14338 // Adding a user requires updating runtime permissions for system apps. 14339 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 14340 } 14341 14342 @Override 14343 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 14344 mContext.enforceCallingOrSelfPermission( 14345 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 14346 "Only package verification agents can read the verifier device identity"); 14347 14348 synchronized (mPackages) { 14349 return mSettings.getVerifierDeviceIdentityLPw(); 14350 } 14351 } 14352 14353 @Override 14354 public void setPermissionEnforced(String permission, boolean enforced) { 14355 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 14356 if (READ_EXTERNAL_STORAGE.equals(permission)) { 14357 synchronized (mPackages) { 14358 if (mSettings.mReadExternalStorageEnforced == null 14359 || mSettings.mReadExternalStorageEnforced != enforced) { 14360 mSettings.mReadExternalStorageEnforced = enforced; 14361 mSettings.writeLPr(); 14362 } 14363 } 14364 // kill any non-foreground processes so we restart them and 14365 // grant/revoke the GID. 14366 final IActivityManager am = ActivityManagerNative.getDefault(); 14367 if (am != null) { 14368 final long token = Binder.clearCallingIdentity(); 14369 try { 14370 am.killProcessesBelowForeground("setPermissionEnforcement"); 14371 } catch (RemoteException e) { 14372 } finally { 14373 Binder.restoreCallingIdentity(token); 14374 } 14375 } 14376 } else { 14377 throw new IllegalArgumentException("No selective enforcement for " + permission); 14378 } 14379 } 14380 14381 @Override 14382 @Deprecated 14383 public boolean isPermissionEnforced(String permission) { 14384 return true; 14385 } 14386 14387 @Override 14388 public boolean isStorageLow() { 14389 final long token = Binder.clearCallingIdentity(); 14390 try { 14391 final DeviceStorageMonitorInternal 14392 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 14393 if (dsm != null) { 14394 return dsm.isMemoryLow(); 14395 } else { 14396 return false; 14397 } 14398 } finally { 14399 Binder.restoreCallingIdentity(token); 14400 } 14401 } 14402 14403 @Override 14404 public IPackageInstaller getPackageInstaller() { 14405 return mInstallerService; 14406 } 14407 14408 private boolean userNeedsBadging(int userId) { 14409 int index = mUserNeedsBadging.indexOfKey(userId); 14410 if (index < 0) { 14411 final UserInfo userInfo; 14412 final long token = Binder.clearCallingIdentity(); 14413 try { 14414 userInfo = sUserManager.getUserInfo(userId); 14415 } finally { 14416 Binder.restoreCallingIdentity(token); 14417 } 14418 final boolean b; 14419 if (userInfo != null && userInfo.isManagedProfile()) { 14420 b = true; 14421 } else { 14422 b = false; 14423 } 14424 mUserNeedsBadging.put(userId, b); 14425 return b; 14426 } 14427 return mUserNeedsBadging.valueAt(index); 14428 } 14429 14430 @Override 14431 public KeySet getKeySetByAlias(String packageName, String alias) { 14432 if (packageName == null || alias == null) { 14433 return null; 14434 } 14435 synchronized(mPackages) { 14436 final PackageParser.Package pkg = mPackages.get(packageName); 14437 if (pkg == null) { 14438 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14439 throw new IllegalArgumentException("Unknown package: " + packageName); 14440 } 14441 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14442 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 14443 } 14444 } 14445 14446 @Override 14447 public KeySet getSigningKeySet(String packageName) { 14448 if (packageName == null) { 14449 return null; 14450 } 14451 synchronized(mPackages) { 14452 final PackageParser.Package pkg = mPackages.get(packageName); 14453 if (pkg == null) { 14454 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14455 throw new IllegalArgumentException("Unknown package: " + packageName); 14456 } 14457 if (pkg.applicationInfo.uid != Binder.getCallingUid() 14458 && Process.SYSTEM_UID != Binder.getCallingUid()) { 14459 throw new SecurityException("May not access signing KeySet of other apps."); 14460 } 14461 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14462 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 14463 } 14464 } 14465 14466 @Override 14467 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 14468 if (packageName == null || ks == null) { 14469 return false; 14470 } 14471 synchronized(mPackages) { 14472 final PackageParser.Package pkg = mPackages.get(packageName); 14473 if (pkg == null) { 14474 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14475 throw new IllegalArgumentException("Unknown package: " + packageName); 14476 } 14477 IBinder ksh = ks.getToken(); 14478 if (ksh instanceof KeySetHandle) { 14479 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14480 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 14481 } 14482 return false; 14483 } 14484 } 14485 14486 @Override 14487 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 14488 if (packageName == null || ks == null) { 14489 return false; 14490 } 14491 synchronized(mPackages) { 14492 final PackageParser.Package pkg = mPackages.get(packageName); 14493 if (pkg == null) { 14494 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14495 throw new IllegalArgumentException("Unknown package: " + packageName); 14496 } 14497 IBinder ksh = ks.getToken(); 14498 if (ksh instanceof KeySetHandle) { 14499 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14500 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 14501 } 14502 return false; 14503 } 14504 } 14505 14506 public void getUsageStatsIfNoPackageUsageInfo() { 14507 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 14508 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 14509 if (usm == null) { 14510 throw new IllegalStateException("UsageStatsManager must be initialized"); 14511 } 14512 long now = System.currentTimeMillis(); 14513 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 14514 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 14515 String packageName = entry.getKey(); 14516 PackageParser.Package pkg = mPackages.get(packageName); 14517 if (pkg == null) { 14518 continue; 14519 } 14520 UsageStats usage = entry.getValue(); 14521 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 14522 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 14523 } 14524 } 14525 } 14526 14527 /** 14528 * Check and throw if the given before/after packages would be considered a 14529 * downgrade. 14530 */ 14531 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 14532 throws PackageManagerException { 14533 if (after.versionCode < before.mVersionCode) { 14534 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14535 "Update version code " + after.versionCode + " is older than current " 14536 + before.mVersionCode); 14537 } else if (after.versionCode == before.mVersionCode) { 14538 if (after.baseRevisionCode < before.baseRevisionCode) { 14539 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14540 "Update base revision code " + after.baseRevisionCode 14541 + " is older than current " + before.baseRevisionCode); 14542 } 14543 14544 if (!ArrayUtils.isEmpty(after.splitNames)) { 14545 for (int i = 0; i < after.splitNames.length; i++) { 14546 final String splitName = after.splitNames[i]; 14547 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 14548 if (j != -1) { 14549 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 14550 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14551 "Update split " + splitName + " revision code " 14552 + after.splitRevisionCodes[i] + " is older than current " 14553 + before.splitRevisionCodes[j]); 14554 } 14555 } 14556 } 14557 } 14558 } 14559 } 14560} 14561