PackageManagerService.java revision dc4ad271f931eca48ab8ef22ef76db740d179d99
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.MATCH_ALL; 53import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 54import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 55import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 56import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 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 android.app.ActivityManager; 75import android.app.ActivityManagerNative; 76import android.app.AppGlobals; 77import android.app.IActivityManager; 78import android.app.admin.IDevicePolicyManager; 79import android.app.backup.IBackupManager; 80import android.app.usage.UsageStats; 81import android.app.usage.UsageStatsManager; 82import android.content.BroadcastReceiver; 83import android.content.ComponentName; 84import android.content.Context; 85import android.content.IIntentReceiver; 86import android.content.Intent; 87import android.content.IntentFilter; 88import android.content.IntentSender; 89import android.content.IntentSender.SendIntentException; 90import android.content.ServiceConnection; 91import android.content.pm.ActivityInfo; 92import android.content.pm.ApplicationInfo; 93import android.content.pm.FeatureInfo; 94import android.content.pm.IPackageDataObserver; 95import android.content.pm.IPackageDeleteObserver; 96import android.content.pm.IPackageDeleteObserver2; 97import android.content.pm.IPackageInstallObserver2; 98import android.content.pm.IPackageInstaller; 99import android.content.pm.IPackageManager; 100import android.content.pm.IPackageMoveObserver; 101import android.content.pm.IPackageStatsObserver; 102import android.content.pm.InstrumentationInfo; 103import android.content.pm.IntentFilterVerificationInfo; 104import android.content.pm.KeySet; 105import android.content.pm.ManifestDigest; 106import android.content.pm.PackageCleanItem; 107import android.content.pm.PackageInfo; 108import android.content.pm.PackageInfoLite; 109import android.content.pm.PackageInstaller; 110import android.content.pm.PackageManager; 111import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 112import android.content.pm.PackageParser; 113import android.content.pm.PackageParser.ActivityIntentInfo; 114import android.content.pm.PackageParser.PackageLite; 115import android.content.pm.PackageParser.PackageParserException; 116import android.content.pm.PackageStats; 117import android.content.pm.PackageUserState; 118import android.content.pm.ParceledListSlice; 119import android.content.pm.PermissionGroupInfo; 120import android.content.pm.PermissionInfo; 121import android.content.pm.ProviderInfo; 122import android.content.pm.ResolveInfo; 123import android.content.pm.ServiceInfo; 124import android.content.pm.Signature; 125import android.content.pm.UserInfo; 126import android.content.pm.VerificationParams; 127import android.content.pm.VerifierDeviceIdentity; 128import android.content.pm.VerifierInfo; 129import android.content.res.Resources; 130import android.hardware.display.DisplayManager; 131import android.net.Uri; 132import android.os.Binder; 133import android.os.Build; 134import android.os.Bundle; 135import android.os.Debug; 136import android.os.Environment; 137import android.os.Environment.UserEnvironment; 138import android.os.FileUtils; 139import android.os.Handler; 140import android.os.IBinder; 141import android.os.Looper; 142import android.os.Message; 143import android.os.Parcel; 144import android.os.ParcelFileDescriptor; 145import android.os.Process; 146import android.os.RemoteCallbackList; 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.os.storage.VolumeRecord; 159import android.security.KeyStore; 160import android.security.SystemKeyStore; 161import android.system.ErrnoException; 162import android.system.Os; 163import android.system.StructStat; 164import android.text.TextUtils; 165import android.text.format.DateUtils; 166import android.util.ArrayMap; 167import android.util.ArraySet; 168import android.util.AtomicFile; 169import android.util.DisplayMetrics; 170import android.util.EventLog; 171import android.util.ExceptionUtils; 172import android.util.Log; 173import android.util.LogPrinter; 174import android.util.PrintStreamPrinter; 175import android.util.Slog; 176import android.util.SparseArray; 177import android.util.SparseBooleanArray; 178import android.util.SparseIntArray; 179import android.util.Xml; 180import android.view.Display; 181 182import dalvik.system.DexFile; 183import dalvik.system.VMRuntime; 184 185import libcore.io.IoUtils; 186import libcore.util.EmptyArray; 187 188import com.android.internal.R; 189import com.android.internal.app.IMediaContainerService; 190import com.android.internal.app.ResolverActivity; 191import com.android.internal.content.NativeLibraryHelper; 192import com.android.internal.content.PackageHelper; 193import com.android.internal.os.IParcelFileDescriptorFactory; 194import com.android.internal.os.SomeArgs; 195import com.android.internal.util.ArrayUtils; 196import com.android.internal.util.FastPrintWriter; 197import com.android.internal.util.FastXmlSerializer; 198import com.android.internal.util.IndentingPrintWriter; 199import com.android.internal.util.Preconditions; 200import com.android.server.EventLogTags; 201import com.android.server.FgThread; 202import com.android.server.IntentResolver; 203import com.android.server.LocalServices; 204import com.android.server.ServiceThread; 205import com.android.server.SystemConfig; 206import com.android.server.Watchdog; 207import com.android.server.pm.Settings.DatabaseVersion; 208import com.android.server.storage.DeviceStorageMonitorInternal; 209 210import org.xmlpull.v1.XmlPullParser; 211import org.xmlpull.v1.XmlSerializer; 212 213import java.io.BufferedInputStream; 214import java.io.BufferedOutputStream; 215import java.io.BufferedReader; 216import java.io.ByteArrayInputStream; 217import java.io.ByteArrayOutputStream; 218import java.io.File; 219import java.io.FileDescriptor; 220import java.io.FileNotFoundException; 221import java.io.FileOutputStream; 222import java.io.FileReader; 223import java.io.FilenameFilter; 224import java.io.IOException; 225import java.io.InputStream; 226import java.io.PrintWriter; 227import java.nio.charset.StandardCharsets; 228import java.security.NoSuchAlgorithmException; 229import java.security.PublicKey; 230import java.security.cert.CertificateEncodingException; 231import java.security.cert.CertificateException; 232import java.text.SimpleDateFormat; 233import java.util.ArrayList; 234import java.util.Arrays; 235import java.util.Collection; 236import java.util.Collections; 237import java.util.Comparator; 238import java.util.Date; 239import java.util.Iterator; 240import java.util.List; 241import java.util.Map; 242import java.util.Objects; 243import java.util.Set; 244import java.util.concurrent.atomic.AtomicBoolean; 245import java.util.concurrent.atomic.AtomicInteger; 246import java.util.concurrent.atomic.AtomicLong; 247 248/** 249 * Keep track of all those .apks everywhere. 250 * 251 * This is very central to the platform's security; please run the unit 252 * tests whenever making modifications here: 253 * 254mmm frameworks/base/tests/AndroidTests 255adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 256adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 257 * 258 * {@hide} 259 */ 260public class PackageManagerService extends IPackageManager.Stub { 261 static final String TAG = "PackageManager"; 262 static final boolean DEBUG_SETTINGS = false; 263 static final boolean DEBUG_PREFERRED = false; 264 static final boolean DEBUG_UPGRADE = false; 265 private static final boolean DEBUG_BACKUP = true; 266 private static final boolean DEBUG_INSTALL = false; 267 private static final boolean DEBUG_REMOVE = false; 268 private static final boolean DEBUG_BROADCASTS = false; 269 private static final boolean DEBUG_SHOW_INFO = false; 270 private static final boolean DEBUG_PACKAGE_INFO = false; 271 private static final boolean DEBUG_INTENT_MATCHING = false; 272 private static final boolean DEBUG_PACKAGE_SCANNING = false; 273 private static final boolean DEBUG_VERIFY = false; 274 private static final boolean DEBUG_DEXOPT = false; 275 private static final boolean DEBUG_ABI_SELECTION = false; 276 277 static final boolean RUNTIME_PERMISSIONS_ENABLED = true; 278 279 private static final int RADIO_UID = Process.PHONE_UID; 280 private static final int LOG_UID = Process.LOG_UID; 281 private static final int NFC_UID = Process.NFC_UID; 282 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 283 private static final int SHELL_UID = Process.SHELL_UID; 284 285 // Cap the size of permission trees that 3rd party apps can define 286 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 287 288 // Suffix used during package installation when copying/moving 289 // package apks to install directory. 290 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 291 292 static final int SCAN_NO_DEX = 1<<1; 293 static final int SCAN_FORCE_DEX = 1<<2; 294 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 295 static final int SCAN_NEW_INSTALL = 1<<4; 296 static final int SCAN_NO_PATHS = 1<<5; 297 static final int SCAN_UPDATE_TIME = 1<<6; 298 static final int SCAN_DEFER_DEX = 1<<7; 299 static final int SCAN_BOOTING = 1<<8; 300 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 301 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 302 static final int SCAN_REQUIRE_KNOWN = 1<<12; 303 304 static final int REMOVE_CHATTY = 1<<16; 305 306 /** 307 * Timeout (in milliseconds) after which the watchdog should declare that 308 * our handler thread is wedged. The usual default for such things is one 309 * minute but we sometimes do very lengthy I/O operations on this thread, 310 * such as installing multi-gigabyte applications, so ours needs to be longer. 311 */ 312 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 313 314 /** 315 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 316 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 317 * settings entry if available, otherwise we use the hardcoded default. If it's been 318 * more than this long since the last fstrim, we force one during the boot sequence. 319 * 320 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 321 * one gets run at the next available charging+idle time. This final mandatory 322 * no-fstrim check kicks in only of the other scheduling criteria is never met. 323 */ 324 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 325 326 /** 327 * Whether verification is enabled by default. 328 */ 329 private static final boolean DEFAULT_VERIFY_ENABLE = true; 330 331 /** 332 * The default maximum time to wait for the verification agent to return in 333 * milliseconds. 334 */ 335 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 336 337 /** 338 * The default response for package verification timeout. 339 * 340 * This can be either PackageManager.VERIFICATION_ALLOW or 341 * PackageManager.VERIFICATION_REJECT. 342 */ 343 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 344 345 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 346 347 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 348 DEFAULT_CONTAINER_PACKAGE, 349 "com.android.defcontainer.DefaultContainerService"); 350 351 private static final String KILL_APP_REASON_GIDS_CHANGED = 352 "permission grant or revoke changed gids"; 353 354 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 355 "permissions revoked"; 356 357 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 358 359 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 360 361 /** Permission grant: not grant the permission. */ 362 private static final int GRANT_DENIED = 1; 363 364 /** Permission grant: grant the permission as an install permission. */ 365 private static final int GRANT_INSTALL = 2; 366 367 /** Permission grant: grant the permission as a runtime one. */ 368 private static final int GRANT_RUNTIME = 3; 369 370 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 371 private static final int GRANT_UPGRADE = 4; 372 373 final ServiceThread mHandlerThread; 374 375 final PackageHandler mHandler; 376 377 /** 378 * Messages for {@link #mHandler} that need to wait for system ready before 379 * being dispatched. 380 */ 381 private ArrayList<Message> mPostSystemReadyMessages; 382 383 final int mSdkVersion = Build.VERSION.SDK_INT; 384 385 final Context mContext; 386 final boolean mFactoryTest; 387 final boolean mOnlyCore; 388 final boolean mLazyDexOpt; 389 final long mDexOptLRUThresholdInMills; 390 final DisplayMetrics mMetrics; 391 final int mDefParseFlags; 392 final String[] mSeparateProcesses; 393 final boolean mIsUpgrade; 394 395 // This is where all application persistent data goes. 396 final File mAppDataDir; 397 398 // This is where all application persistent data goes for secondary users. 399 final File mUserAppDataDir; 400 401 /** The location for ASEC container files on internal storage. */ 402 final String mAsecInternalPath; 403 404 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 405 // LOCK HELD. Can be called with mInstallLock held. 406 final Installer mInstaller; 407 408 /** Directory where installed third-party apps stored */ 409 final File mAppInstallDir; 410 411 /** 412 * Directory to which applications installed internally have their 413 * 32 bit native libraries copied. 414 */ 415 private File mAppLib32InstallDir; 416 417 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 418 // apps. 419 final File mDrmAppPrivateInstallDir; 420 421 // ---------------------------------------------------------------- 422 423 // Lock for state used when installing and doing other long running 424 // operations. Methods that must be called with this lock held have 425 // the suffix "LI". 426 final Object mInstallLock = new Object(); 427 428 // ---------------------------------------------------------------- 429 430 // Keys are String (package name), values are Package. This also serves 431 // as the lock for the global state. Methods that must be called with 432 // this lock held have the prefix "LP". 433 final ArrayMap<String, PackageParser.Package> mPackages = 434 new ArrayMap<String, PackageParser.Package>(); 435 436 // Tracks available target package names -> overlay package paths. 437 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 438 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 439 440 final Settings mSettings; 441 boolean mRestoredSettings; 442 443 // System configuration read by SystemConfig. 444 final int[] mGlobalGids; 445 final SparseArray<ArraySet<String>> mSystemPermissions; 446 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 447 448 // If mac_permissions.xml was found for seinfo labeling. 449 boolean mFoundPolicyFile; 450 451 // If a recursive restorecon of /data/data/<pkg> is needed. 452 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 453 454 public static final class SharedLibraryEntry { 455 public final String path; 456 public final String apk; 457 458 SharedLibraryEntry(String _path, String _apk) { 459 path = _path; 460 apk = _apk; 461 } 462 } 463 464 // Currently known shared libraries. 465 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 466 new ArrayMap<String, SharedLibraryEntry>(); 467 468 // All available activities, for your resolving pleasure. 469 final ActivityIntentResolver mActivities = 470 new ActivityIntentResolver(); 471 472 // All available receivers, for your resolving pleasure. 473 final ActivityIntentResolver mReceivers = 474 new ActivityIntentResolver(); 475 476 // All available services, for your resolving pleasure. 477 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 478 479 // All available providers, for your resolving pleasure. 480 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 481 482 // Mapping from provider base names (first directory in content URI codePath) 483 // to the provider information. 484 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 485 new ArrayMap<String, PackageParser.Provider>(); 486 487 // Mapping from instrumentation class names to info about them. 488 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 489 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 490 491 // Mapping from permission names to info about them. 492 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 493 new ArrayMap<String, PackageParser.PermissionGroup>(); 494 495 // Packages whose data we have transfered into another package, thus 496 // should no longer exist. 497 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 498 499 // Broadcast actions that are only available to the system. 500 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 501 502 /** List of packages waiting for verification. */ 503 final SparseArray<PackageVerificationState> mPendingVerification 504 = new SparseArray<PackageVerificationState>(); 505 506 /** Set of packages associated with each app op permission. */ 507 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 508 509 final PackageInstallerService mInstallerService; 510 511 private final PackageDexOptimizer mPackageDexOptimizer; 512 513 private AtomicInteger mNextMoveId = new AtomicInteger(); 514 private final MoveCallbacks mMoveCallbacks; 515 516 // Cache of users who need badging. 517 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 518 519 /** Token for keys in mPendingVerification. */ 520 private int mPendingVerificationToken = 0; 521 522 volatile boolean mSystemReady; 523 volatile boolean mSafeMode; 524 volatile boolean mHasSystemUidErrors; 525 526 ApplicationInfo mAndroidApplication; 527 final ActivityInfo mResolveActivity = new ActivityInfo(); 528 final ResolveInfo mResolveInfo = new ResolveInfo(); 529 ComponentName mResolveComponentName; 530 PackageParser.Package mPlatformPackage; 531 ComponentName mCustomResolverComponentName; 532 533 boolean mResolverReplaced = false; 534 535 private final ComponentName mIntentFilterVerifierComponent; 536 private int mIntentFilterVerificationToken = 0; 537 538 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 539 = new SparseArray<IntentFilterVerificationState>(); 540 541 private interface IntentFilterVerifier<T extends IntentFilter> { 542 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 543 T filter, String packageName); 544 void startVerifications(int userId); 545 void receiveVerificationResponse(int verificationId); 546 } 547 548 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 549 private Context mContext; 550 private ComponentName mIntentFilterVerifierComponent; 551 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 552 553 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 554 mContext = context; 555 mIntentFilterVerifierComponent = verifierComponent; 556 } 557 558 private String getDefaultScheme() { 559 // TODO: replace SCHEME_HTTP with SCHEME_HTTPS 560 return IntentFilter.SCHEME_HTTP; 561 } 562 563 @Override 564 public void startVerifications(int userId) { 565 // Launch verifications requests 566 int count = mCurrentIntentFilterVerifications.size(); 567 for (int n=0; n<count; n++) { 568 int verificationId = mCurrentIntentFilterVerifications.get(n); 569 final IntentFilterVerificationState ivs = 570 mIntentFilterVerificationStates.get(verificationId); 571 572 String packageName = ivs.getPackageName(); 573 574 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 575 final int filterCount = filters.size(); 576 ArraySet<String> domainsSet = new ArraySet<>(); 577 for (int m=0; m<filterCount; m++) { 578 PackageParser.ActivityIntentInfo filter = filters.get(m); 579 domainsSet.addAll(filter.getHostsList()); 580 } 581 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 582 synchronized (mPackages) { 583 if (mSettings.createIntentFilterVerificationIfNeededLPw( 584 packageName, domainsList) != null) { 585 scheduleWriteSettingsLocked(); 586 } 587 } 588 sendVerificationRequest(userId, verificationId, ivs); 589 } 590 mCurrentIntentFilterVerifications.clear(); 591 } 592 593 private void sendVerificationRequest(int userId, int verificationId, 594 IntentFilterVerificationState ivs) { 595 596 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 597 verificationIntent.putExtra( 598 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 599 verificationId); 600 verificationIntent.putExtra( 601 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 602 getDefaultScheme()); 603 verificationIntent.putExtra( 604 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 605 ivs.getHostsString()); 606 verificationIntent.putExtra( 607 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 608 ivs.getPackageName()); 609 verificationIntent.setComponent(mIntentFilterVerifierComponent); 610 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 611 612 UserHandle user = new UserHandle(userId); 613 mContext.sendBroadcastAsUser(verificationIntent, user); 614 Slog.d(TAG, "Sending IntenFilter verification broadcast"); 615 } 616 617 public void receiveVerificationResponse(int verificationId) { 618 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 619 620 final boolean verified = ivs.isVerified(); 621 622 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 623 final int count = filters.size(); 624 for (int n=0; n<count; n++) { 625 PackageParser.ActivityIntentInfo filter = filters.get(n); 626 filter.setVerified(verified); 627 628 Slog.d(TAG, "IntentFilter " + filter.toString() + " verified with result:" 629 + verified + " and hosts:" + ivs.getHostsString()); 630 } 631 632 mIntentFilterVerificationStates.remove(verificationId); 633 634 final String packageName = ivs.getPackageName(); 635 IntentFilterVerificationInfo ivi = null; 636 637 synchronized (mPackages) { 638 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 639 } 640 if (ivi == null) { 641 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 642 + verificationId + " packageName:" + packageName); 643 return; 644 } 645 Slog.d(TAG, "Updating IntentFilterVerificationInfo for verificationId:" 646 + verificationId); 647 648 synchronized (mPackages) { 649 if (verified) { 650 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 651 } else { 652 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 653 } 654 scheduleWriteSettingsLocked(); 655 656 final int userId = ivs.getUserId(); 657 if (userId != UserHandle.USER_ALL) { 658 final int userStatus = 659 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 660 661 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 662 boolean needUpdate = false; 663 664 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 665 // already been set by the User thru the Disambiguation dialog 666 switch (userStatus) { 667 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 668 if (verified) { 669 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 670 } else { 671 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 672 } 673 needUpdate = true; 674 break; 675 676 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 677 if (verified) { 678 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 679 needUpdate = true; 680 } 681 break; 682 683 default: 684 // Nothing to do 685 } 686 687 if (needUpdate) { 688 mSettings.updateIntentFilterVerificationStatusLPw( 689 packageName, updatedStatus, userId); 690 scheduleWritePackageRestrictionsLocked(userId); 691 } 692 } 693 } 694 } 695 696 @Override 697 public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 698 ActivityIntentInfo filter, String packageName) { 699 if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 700 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 701 Slog.d(TAG, "IntentFilter does not contain HTTP nor HTTPS data scheme"); 702 return false; 703 } 704 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 705 if (ivs == null) { 706 ivs = createDomainVerificationState(verifierId, userId, verificationId, 707 packageName); 708 } 709 if (!hasValidDomains(filter)) { 710 return false; 711 } 712 ivs.addFilter(filter); 713 return true; 714 } 715 716 private IntentFilterVerificationState createDomainVerificationState(int verifierId, 717 int userId, int verificationId, String packageName) { 718 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 719 verifierId, userId, packageName); 720 ivs.setPendingState(); 721 synchronized (mPackages) { 722 mIntentFilterVerificationStates.append(verificationId, ivs); 723 mCurrentIntentFilterVerifications.add(verificationId); 724 } 725 return ivs; 726 } 727 } 728 729 private static boolean hasValidDomains(ActivityIntentInfo filter) { 730 return hasValidDomains(filter, true); 731 } 732 733 private static boolean hasValidDomains(ActivityIntentInfo filter, boolean logging) { 734 boolean hasHTTPorHTTPS = filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 735 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS); 736 if (!hasHTTPorHTTPS) { 737 if (logging) { 738 Slog.d(TAG, "IntentFilter does not contain any HTTP or HTTPS data scheme"); 739 } 740 return false; 741 } 742 return true; 743 } 744 745 private IntentFilterVerifier mIntentFilterVerifier; 746 747 // Set of pending broadcasts for aggregating enable/disable of components. 748 static class PendingPackageBroadcasts { 749 // for each user id, a map of <package name -> components within that package> 750 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 751 752 public PendingPackageBroadcasts() { 753 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 754 } 755 756 public ArrayList<String> get(int userId, String packageName) { 757 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 758 return packages.get(packageName); 759 } 760 761 public void put(int userId, String packageName, ArrayList<String> components) { 762 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 763 packages.put(packageName, components); 764 } 765 766 public void remove(int userId, String packageName) { 767 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 768 if (packages != null) { 769 packages.remove(packageName); 770 } 771 } 772 773 public void remove(int userId) { 774 mUidMap.remove(userId); 775 } 776 777 public int userIdCount() { 778 return mUidMap.size(); 779 } 780 781 public int userIdAt(int n) { 782 return mUidMap.keyAt(n); 783 } 784 785 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 786 return mUidMap.get(userId); 787 } 788 789 public int size() { 790 // total number of pending broadcast entries across all userIds 791 int num = 0; 792 for (int i = 0; i< mUidMap.size(); i++) { 793 num += mUidMap.valueAt(i).size(); 794 } 795 return num; 796 } 797 798 public void clear() { 799 mUidMap.clear(); 800 } 801 802 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 803 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 804 if (map == null) { 805 map = new ArrayMap<String, ArrayList<String>>(); 806 mUidMap.put(userId, map); 807 } 808 return map; 809 } 810 } 811 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 812 813 // Service Connection to remote media container service to copy 814 // package uri's from external media onto secure containers 815 // or internal storage. 816 private IMediaContainerService mContainerService = null; 817 818 static final int SEND_PENDING_BROADCAST = 1; 819 static final int MCS_BOUND = 3; 820 static final int END_COPY = 4; 821 static final int INIT_COPY = 5; 822 static final int MCS_UNBIND = 6; 823 static final int START_CLEANING_PACKAGE = 7; 824 static final int FIND_INSTALL_LOC = 8; 825 static final int POST_INSTALL = 9; 826 static final int MCS_RECONNECT = 10; 827 static final int MCS_GIVE_UP = 11; 828 static final int UPDATED_MEDIA_STATUS = 12; 829 static final int WRITE_SETTINGS = 13; 830 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 831 static final int PACKAGE_VERIFIED = 15; 832 static final int CHECK_PENDING_VERIFICATION = 16; 833 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 834 static final int INTENT_FILTER_VERIFIED = 18; 835 836 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 837 838 // Delay time in millisecs 839 static final int BROADCAST_DELAY = 10 * 1000; 840 841 static UserManagerService sUserManager; 842 843 // Stores a list of users whose package restrictions file needs to be updated 844 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 845 846 final private DefaultContainerConnection mDefContainerConn = 847 new DefaultContainerConnection(); 848 class DefaultContainerConnection implements ServiceConnection { 849 public void onServiceConnected(ComponentName name, IBinder service) { 850 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 851 IMediaContainerService imcs = 852 IMediaContainerService.Stub.asInterface(service); 853 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 854 } 855 856 public void onServiceDisconnected(ComponentName name) { 857 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 858 } 859 }; 860 861 // Recordkeeping of restore-after-install operations that are currently in flight 862 // between the Package Manager and the Backup Manager 863 class PostInstallData { 864 public InstallArgs args; 865 public PackageInstalledInfo res; 866 867 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 868 args = _a; 869 res = _r; 870 } 871 }; 872 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 873 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 874 875 // backup/restore of preferred activity state 876 private static final String TAG_PREFERRED_BACKUP = "pa"; 877 878 private final String mRequiredVerifierPackage; 879 880 private final PackageUsage mPackageUsage = new PackageUsage(); 881 882 private class PackageUsage { 883 private static final int WRITE_INTERVAL 884 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 885 886 private final Object mFileLock = new Object(); 887 private final AtomicLong mLastWritten = new AtomicLong(0); 888 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 889 890 private boolean mIsHistoricalPackageUsageAvailable = true; 891 892 boolean isHistoricalPackageUsageAvailable() { 893 return mIsHistoricalPackageUsageAvailable; 894 } 895 896 void write(boolean force) { 897 if (force) { 898 writeInternal(); 899 return; 900 } 901 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 902 && !DEBUG_DEXOPT) { 903 return; 904 } 905 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 906 new Thread("PackageUsage_DiskWriter") { 907 @Override 908 public void run() { 909 try { 910 writeInternal(); 911 } finally { 912 mBackgroundWriteRunning.set(false); 913 } 914 } 915 }.start(); 916 } 917 } 918 919 private void writeInternal() { 920 synchronized (mPackages) { 921 synchronized (mFileLock) { 922 AtomicFile file = getFile(); 923 FileOutputStream f = null; 924 try { 925 f = file.startWrite(); 926 BufferedOutputStream out = new BufferedOutputStream(f); 927 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 928 StringBuilder sb = new StringBuilder(); 929 for (PackageParser.Package pkg : mPackages.values()) { 930 if (pkg.mLastPackageUsageTimeInMills == 0) { 931 continue; 932 } 933 sb.setLength(0); 934 sb.append(pkg.packageName); 935 sb.append(' '); 936 sb.append((long)pkg.mLastPackageUsageTimeInMills); 937 sb.append('\n'); 938 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 939 } 940 out.flush(); 941 file.finishWrite(f); 942 } catch (IOException e) { 943 if (f != null) { 944 file.failWrite(f); 945 } 946 Log.e(TAG, "Failed to write package usage times", e); 947 } 948 } 949 } 950 mLastWritten.set(SystemClock.elapsedRealtime()); 951 } 952 953 void readLP() { 954 synchronized (mFileLock) { 955 AtomicFile file = getFile(); 956 BufferedInputStream in = null; 957 try { 958 in = new BufferedInputStream(file.openRead()); 959 StringBuffer sb = new StringBuffer(); 960 while (true) { 961 String packageName = readToken(in, sb, ' '); 962 if (packageName == null) { 963 break; 964 } 965 String timeInMillisString = readToken(in, sb, '\n'); 966 if (timeInMillisString == null) { 967 throw new IOException("Failed to find last usage time for package " 968 + packageName); 969 } 970 PackageParser.Package pkg = mPackages.get(packageName); 971 if (pkg == null) { 972 continue; 973 } 974 long timeInMillis; 975 try { 976 timeInMillis = Long.parseLong(timeInMillisString.toString()); 977 } catch (NumberFormatException e) { 978 throw new IOException("Failed to parse " + timeInMillisString 979 + " as a long.", e); 980 } 981 pkg.mLastPackageUsageTimeInMills = timeInMillis; 982 } 983 } catch (FileNotFoundException expected) { 984 mIsHistoricalPackageUsageAvailable = false; 985 } catch (IOException e) { 986 Log.w(TAG, "Failed to read package usage times", e); 987 } finally { 988 IoUtils.closeQuietly(in); 989 } 990 } 991 mLastWritten.set(SystemClock.elapsedRealtime()); 992 } 993 994 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 995 throws IOException { 996 sb.setLength(0); 997 while (true) { 998 int ch = in.read(); 999 if (ch == -1) { 1000 if (sb.length() == 0) { 1001 return null; 1002 } 1003 throw new IOException("Unexpected EOF"); 1004 } 1005 if (ch == endOfToken) { 1006 return sb.toString(); 1007 } 1008 sb.append((char)ch); 1009 } 1010 } 1011 1012 private AtomicFile getFile() { 1013 File dataDir = Environment.getDataDirectory(); 1014 File systemDir = new File(dataDir, "system"); 1015 File fname = new File(systemDir, "package-usage.list"); 1016 return new AtomicFile(fname); 1017 } 1018 } 1019 1020 class PackageHandler extends Handler { 1021 private boolean mBound = false; 1022 final ArrayList<HandlerParams> mPendingInstalls = 1023 new ArrayList<HandlerParams>(); 1024 1025 private boolean connectToService() { 1026 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1027 " DefaultContainerService"); 1028 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1029 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1030 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1031 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 1032 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1033 mBound = true; 1034 return true; 1035 } 1036 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1037 return false; 1038 } 1039 1040 private void disconnectService() { 1041 mContainerService = null; 1042 mBound = false; 1043 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1044 mContext.unbindService(mDefContainerConn); 1045 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1046 } 1047 1048 PackageHandler(Looper looper) { 1049 super(looper); 1050 } 1051 1052 public void handleMessage(Message msg) { 1053 try { 1054 doHandleMessage(msg); 1055 } finally { 1056 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1057 } 1058 } 1059 1060 void doHandleMessage(Message msg) { 1061 switch (msg.what) { 1062 case INIT_COPY: { 1063 HandlerParams params = (HandlerParams) msg.obj; 1064 int idx = mPendingInstalls.size(); 1065 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1066 // If a bind was already initiated we dont really 1067 // need to do anything. The pending install 1068 // will be processed later on. 1069 if (!mBound) { 1070 // If this is the only one pending we might 1071 // have to bind to the service again. 1072 if (!connectToService()) { 1073 Slog.e(TAG, "Failed to bind to media container service"); 1074 params.serviceError(); 1075 return; 1076 } else { 1077 // Once we bind to the service, the first 1078 // pending request will be processed. 1079 mPendingInstalls.add(idx, params); 1080 } 1081 } else { 1082 mPendingInstalls.add(idx, params); 1083 // Already bound to the service. Just make 1084 // sure we trigger off processing the first request. 1085 if (idx == 0) { 1086 mHandler.sendEmptyMessage(MCS_BOUND); 1087 } 1088 } 1089 break; 1090 } 1091 case MCS_BOUND: { 1092 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1093 if (msg.obj != null) { 1094 mContainerService = (IMediaContainerService) msg.obj; 1095 } 1096 if (mContainerService == null) { 1097 // Something seriously wrong. Bail out 1098 Slog.e(TAG, "Cannot bind to media container service"); 1099 for (HandlerParams params : mPendingInstalls) { 1100 // Indicate service bind error 1101 params.serviceError(); 1102 } 1103 mPendingInstalls.clear(); 1104 } else if (mPendingInstalls.size() > 0) { 1105 HandlerParams params = mPendingInstalls.get(0); 1106 if (params != null) { 1107 if (params.startCopy()) { 1108 // We are done... look for more work or to 1109 // go idle. 1110 if (DEBUG_SD_INSTALL) Log.i(TAG, 1111 "Checking for more work or unbind..."); 1112 // Delete pending install 1113 if (mPendingInstalls.size() > 0) { 1114 mPendingInstalls.remove(0); 1115 } 1116 if (mPendingInstalls.size() == 0) { 1117 if (mBound) { 1118 if (DEBUG_SD_INSTALL) Log.i(TAG, 1119 "Posting delayed MCS_UNBIND"); 1120 removeMessages(MCS_UNBIND); 1121 Message ubmsg = obtainMessage(MCS_UNBIND); 1122 // Unbind after a little delay, to avoid 1123 // continual thrashing. 1124 sendMessageDelayed(ubmsg, 10000); 1125 } 1126 } else { 1127 // There are more pending requests in queue. 1128 // Just post MCS_BOUND message to trigger processing 1129 // of next pending install. 1130 if (DEBUG_SD_INSTALL) Log.i(TAG, 1131 "Posting MCS_BOUND for next work"); 1132 mHandler.sendEmptyMessage(MCS_BOUND); 1133 } 1134 } 1135 } 1136 } else { 1137 // Should never happen ideally. 1138 Slog.w(TAG, "Empty queue"); 1139 } 1140 break; 1141 } 1142 case MCS_RECONNECT: { 1143 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1144 if (mPendingInstalls.size() > 0) { 1145 if (mBound) { 1146 disconnectService(); 1147 } 1148 if (!connectToService()) { 1149 Slog.e(TAG, "Failed to bind to media container service"); 1150 for (HandlerParams params : mPendingInstalls) { 1151 // Indicate service bind error 1152 params.serviceError(); 1153 } 1154 mPendingInstalls.clear(); 1155 } 1156 } 1157 break; 1158 } 1159 case MCS_UNBIND: { 1160 // If there is no actual work left, then time to unbind. 1161 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1162 1163 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1164 if (mBound) { 1165 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1166 1167 disconnectService(); 1168 } 1169 } else if (mPendingInstalls.size() > 0) { 1170 // There are more pending requests in queue. 1171 // Just post MCS_BOUND message to trigger processing 1172 // of next pending install. 1173 mHandler.sendEmptyMessage(MCS_BOUND); 1174 } 1175 1176 break; 1177 } 1178 case MCS_GIVE_UP: { 1179 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1180 mPendingInstalls.remove(0); 1181 break; 1182 } 1183 case SEND_PENDING_BROADCAST: { 1184 String packages[]; 1185 ArrayList<String> components[]; 1186 int size = 0; 1187 int uids[]; 1188 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1189 synchronized (mPackages) { 1190 if (mPendingBroadcasts == null) { 1191 return; 1192 } 1193 size = mPendingBroadcasts.size(); 1194 if (size <= 0) { 1195 // Nothing to be done. Just return 1196 return; 1197 } 1198 packages = new String[size]; 1199 components = new ArrayList[size]; 1200 uids = new int[size]; 1201 int i = 0; // filling out the above arrays 1202 1203 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1204 int packageUserId = mPendingBroadcasts.userIdAt(n); 1205 Iterator<Map.Entry<String, ArrayList<String>>> it 1206 = mPendingBroadcasts.packagesForUserId(packageUserId) 1207 .entrySet().iterator(); 1208 while (it.hasNext() && i < size) { 1209 Map.Entry<String, ArrayList<String>> ent = it.next(); 1210 packages[i] = ent.getKey(); 1211 components[i] = ent.getValue(); 1212 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1213 uids[i] = (ps != null) 1214 ? UserHandle.getUid(packageUserId, ps.appId) 1215 : -1; 1216 i++; 1217 } 1218 } 1219 size = i; 1220 mPendingBroadcasts.clear(); 1221 } 1222 // Send broadcasts 1223 for (int i = 0; i < size; i++) { 1224 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1225 } 1226 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1227 break; 1228 } 1229 case START_CLEANING_PACKAGE: { 1230 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1231 final String packageName = (String)msg.obj; 1232 final int userId = msg.arg1; 1233 final boolean andCode = msg.arg2 != 0; 1234 synchronized (mPackages) { 1235 if (userId == UserHandle.USER_ALL) { 1236 int[] users = sUserManager.getUserIds(); 1237 for (int user : users) { 1238 mSettings.addPackageToCleanLPw( 1239 new PackageCleanItem(user, packageName, andCode)); 1240 } 1241 } else { 1242 mSettings.addPackageToCleanLPw( 1243 new PackageCleanItem(userId, packageName, andCode)); 1244 } 1245 } 1246 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1247 startCleaningPackages(); 1248 } break; 1249 case POST_INSTALL: { 1250 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1251 PostInstallData data = mRunningInstalls.get(msg.arg1); 1252 mRunningInstalls.delete(msg.arg1); 1253 boolean deleteOld = false; 1254 1255 if (data != null) { 1256 InstallArgs args = data.args; 1257 PackageInstalledInfo res = data.res; 1258 1259 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1260 res.removedInfo.sendBroadcast(false, true, false); 1261 Bundle extras = new Bundle(1); 1262 extras.putInt(Intent.EXTRA_UID, res.uid); 1263 1264 // Now that we successfully installed the package, grant runtime 1265 // permissions if requested before broadcasting the install. 1266 if ((args.installFlags 1267 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { 1268 grantRequestedRuntimePermissions(res.pkg, 1269 args.user.getIdentifier()); 1270 } 1271 1272 // Determine the set of users who are adding this 1273 // package for the first time vs. those who are seeing 1274 // an update. 1275 int[] firstUsers; 1276 int[] updateUsers = new int[0]; 1277 if (res.origUsers == null || res.origUsers.length == 0) { 1278 firstUsers = res.newUsers; 1279 } else { 1280 firstUsers = new int[0]; 1281 for (int i=0; i<res.newUsers.length; i++) { 1282 int user = res.newUsers[i]; 1283 boolean isNew = true; 1284 for (int j=0; j<res.origUsers.length; j++) { 1285 if (res.origUsers[j] == user) { 1286 isNew = false; 1287 break; 1288 } 1289 } 1290 if (isNew) { 1291 int[] newFirst = new int[firstUsers.length+1]; 1292 System.arraycopy(firstUsers, 0, newFirst, 0, 1293 firstUsers.length); 1294 newFirst[firstUsers.length] = user; 1295 firstUsers = newFirst; 1296 } else { 1297 int[] newUpdate = new int[updateUsers.length+1]; 1298 System.arraycopy(updateUsers, 0, newUpdate, 0, 1299 updateUsers.length); 1300 newUpdate[updateUsers.length] = user; 1301 updateUsers = newUpdate; 1302 } 1303 } 1304 } 1305 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1306 res.pkg.applicationInfo.packageName, 1307 extras, null, null, firstUsers); 1308 final boolean update = res.removedInfo.removedPackage != null; 1309 if (update) { 1310 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1311 } 1312 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1313 res.pkg.applicationInfo.packageName, 1314 extras, null, null, updateUsers); 1315 if (update) { 1316 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1317 res.pkg.applicationInfo.packageName, 1318 extras, null, null, updateUsers); 1319 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1320 null, null, 1321 res.pkg.applicationInfo.packageName, null, updateUsers); 1322 1323 // treat asec-hosted packages like removable media on upgrade 1324 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1325 if (DEBUG_INSTALL) { 1326 Slog.i(TAG, "upgrading pkg " + res.pkg 1327 + " is ASEC-hosted -> AVAILABLE"); 1328 } 1329 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1330 ArrayList<String> pkgList = new ArrayList<String>(1); 1331 pkgList.add(res.pkg.applicationInfo.packageName); 1332 sendResourcesChangedBroadcast(true, true, 1333 pkgList,uidArray, null); 1334 } 1335 } 1336 if (res.removedInfo.args != null) { 1337 // Remove the replaced package's older resources safely now 1338 deleteOld = true; 1339 } 1340 1341 // Log current value of "unknown sources" setting 1342 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1343 getUnknownSourcesSettings()); 1344 } 1345 // Force a gc to clear up things 1346 Runtime.getRuntime().gc(); 1347 // We delete after a gc for applications on sdcard. 1348 if (deleteOld) { 1349 synchronized (mInstallLock) { 1350 res.removedInfo.args.doPostDeleteLI(true); 1351 } 1352 } 1353 if (args.observer != null) { 1354 try { 1355 Bundle extras = extrasForInstallResult(res); 1356 args.observer.onPackageInstalled(res.name, res.returnCode, 1357 res.returnMsg, extras); 1358 } catch (RemoteException e) { 1359 Slog.i(TAG, "Observer no longer exists."); 1360 } 1361 } 1362 } else { 1363 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1364 } 1365 } break; 1366 case UPDATED_MEDIA_STATUS: { 1367 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1368 boolean reportStatus = msg.arg1 == 1; 1369 boolean doGc = msg.arg2 == 1; 1370 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1371 if (doGc) { 1372 // Force a gc to clear up stale containers. 1373 Runtime.getRuntime().gc(); 1374 } 1375 if (msg.obj != null) { 1376 @SuppressWarnings("unchecked") 1377 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1378 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1379 // Unload containers 1380 unloadAllContainers(args); 1381 } 1382 if (reportStatus) { 1383 try { 1384 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1385 PackageHelper.getMountService().finishMediaUpdate(); 1386 } catch (RemoteException e) { 1387 Log.e(TAG, "MountService not running?"); 1388 } 1389 } 1390 } break; 1391 case WRITE_SETTINGS: { 1392 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1393 synchronized (mPackages) { 1394 removeMessages(WRITE_SETTINGS); 1395 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1396 mSettings.writeLPr(); 1397 mDirtyUsers.clear(); 1398 } 1399 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1400 } break; 1401 case WRITE_PACKAGE_RESTRICTIONS: { 1402 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1403 synchronized (mPackages) { 1404 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1405 for (int userId : mDirtyUsers) { 1406 mSettings.writePackageRestrictionsLPr(userId); 1407 } 1408 mDirtyUsers.clear(); 1409 } 1410 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1411 } break; 1412 case CHECK_PENDING_VERIFICATION: { 1413 final int verificationId = msg.arg1; 1414 final PackageVerificationState state = mPendingVerification.get(verificationId); 1415 1416 if ((state != null) && !state.timeoutExtended()) { 1417 final InstallArgs args = state.getInstallArgs(); 1418 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1419 1420 Slog.i(TAG, "Verification timed out for " + originUri); 1421 mPendingVerification.remove(verificationId); 1422 1423 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1424 1425 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1426 Slog.i(TAG, "Continuing with installation of " + originUri); 1427 state.setVerifierResponse(Binder.getCallingUid(), 1428 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1429 broadcastPackageVerified(verificationId, originUri, 1430 PackageManager.VERIFICATION_ALLOW, 1431 state.getInstallArgs().getUser()); 1432 try { 1433 ret = args.copyApk(mContainerService, true); 1434 } catch (RemoteException e) { 1435 Slog.e(TAG, "Could not contact the ContainerService"); 1436 } 1437 } else { 1438 broadcastPackageVerified(verificationId, originUri, 1439 PackageManager.VERIFICATION_REJECT, 1440 state.getInstallArgs().getUser()); 1441 } 1442 1443 processPendingInstall(args, ret); 1444 mHandler.sendEmptyMessage(MCS_UNBIND); 1445 } 1446 break; 1447 } 1448 case PACKAGE_VERIFIED: { 1449 final int verificationId = msg.arg1; 1450 1451 final PackageVerificationState state = mPendingVerification.get(verificationId); 1452 if (state == null) { 1453 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1454 break; 1455 } 1456 1457 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1458 1459 state.setVerifierResponse(response.callerUid, response.code); 1460 1461 if (state.isVerificationComplete()) { 1462 mPendingVerification.remove(verificationId); 1463 1464 final InstallArgs args = state.getInstallArgs(); 1465 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1466 1467 int ret; 1468 if (state.isInstallAllowed()) { 1469 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1470 broadcastPackageVerified(verificationId, originUri, 1471 response.code, state.getInstallArgs().getUser()); 1472 try { 1473 ret = args.copyApk(mContainerService, true); 1474 } catch (RemoteException e) { 1475 Slog.e(TAG, "Could not contact the ContainerService"); 1476 } 1477 } else { 1478 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1479 } 1480 1481 processPendingInstall(args, ret); 1482 1483 mHandler.sendEmptyMessage(MCS_UNBIND); 1484 } 1485 1486 break; 1487 } 1488 case START_INTENT_FILTER_VERIFICATIONS: { 1489 int userId = msg.arg1; 1490 int verifierUid = msg.arg2; 1491 PackageParser.Package pkg = (PackageParser.Package)msg.obj; 1492 1493 verifyIntentFiltersIfNeeded(userId, verifierUid, pkg); 1494 break; 1495 } 1496 case INTENT_FILTER_VERIFIED: { 1497 final int verificationId = msg.arg1; 1498 1499 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1500 verificationId); 1501 if (state == null) { 1502 Slog.w(TAG, "Invalid IntentFilter verification token " 1503 + verificationId + " received"); 1504 break; 1505 } 1506 1507 final int userId = state.getUserId(); 1508 1509 Slog.d(TAG, "Processing IntentFilter verification with token:" 1510 + verificationId + " and userId:" + userId); 1511 1512 final IntentFilterVerificationResponse response = 1513 (IntentFilterVerificationResponse) msg.obj; 1514 1515 state.setVerifierResponse(response.callerUid, response.code); 1516 1517 Slog.d(TAG, "IntentFilter verification with token:" + verificationId 1518 + " and userId:" + userId 1519 + " is settings verifier response with response code:" 1520 + response.code); 1521 1522 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1523 Slog.d(TAG, "Domains failing verification: " 1524 + response.getFailedDomainsString()); 1525 } 1526 1527 if (state.isVerificationComplete()) { 1528 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1529 } else { 1530 Slog.d(TAG, "IntentFilter verification with token:" + verificationId 1531 + " was not said to be complete"); 1532 } 1533 1534 break; 1535 } 1536 } 1537 } 1538 } 1539 1540 private StorageEventListener mStorageListener = new StorageEventListener() { 1541 @Override 1542 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1543 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1544 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1545 // TODO: ensure that private directories exist for all active users 1546 // TODO: remove user data whose serial number doesn't match 1547 loadPrivatePackages(vol); 1548 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1549 unloadPrivatePackages(vol); 1550 } 1551 } 1552 1553 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1554 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1555 updateExternalMediaStatus(true, false); 1556 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1557 updateExternalMediaStatus(false, false); 1558 } 1559 } 1560 } 1561 1562 @Override 1563 public void onVolumeForgotten(String fsUuid) { 1564 // TODO: remove all packages hosted on this uuid 1565 } 1566 }; 1567 1568 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) { 1569 if (userId >= UserHandle.USER_OWNER) { 1570 grantRequestedRuntimePermissionsForUser(pkg, userId); 1571 } else if (userId == UserHandle.USER_ALL) { 1572 for (int someUserId : UserManagerService.getInstance().getUserIds()) { 1573 grantRequestedRuntimePermissionsForUser(pkg, someUserId); 1574 } 1575 } 1576 } 1577 1578 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) { 1579 SettingBase sb = (SettingBase) pkg.mExtras; 1580 if (sb == null) { 1581 return; 1582 } 1583 1584 PermissionsState permissionsState = sb.getPermissionsState(); 1585 1586 for (String permission : pkg.requestedPermissions) { 1587 BasePermission bp = mSettings.mPermissions.get(permission); 1588 if (bp != null && bp.isRuntime()) { 1589 permissionsState.grantRuntimePermission(bp, userId); 1590 } 1591 } 1592 } 1593 1594 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1595 Bundle extras = null; 1596 switch (res.returnCode) { 1597 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1598 extras = new Bundle(); 1599 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1600 res.origPermission); 1601 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1602 res.origPackage); 1603 break; 1604 } 1605 case PackageManager.INSTALL_SUCCEEDED: { 1606 extras = new Bundle(); 1607 extras.putBoolean(Intent.EXTRA_REPLACING, 1608 res.removedInfo != null && res.removedInfo.removedPackage != null); 1609 break; 1610 } 1611 } 1612 return extras; 1613 } 1614 1615 void scheduleWriteSettingsLocked() { 1616 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1617 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1618 } 1619 } 1620 1621 void scheduleWritePackageRestrictionsLocked(int userId) { 1622 if (!sUserManager.exists(userId)) return; 1623 mDirtyUsers.add(userId); 1624 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1625 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1626 } 1627 } 1628 1629 public static PackageManagerService main(Context context, Installer installer, 1630 boolean factoryTest, boolean onlyCore) { 1631 PackageManagerService m = new PackageManagerService(context, installer, 1632 factoryTest, onlyCore); 1633 ServiceManager.addService("package", m); 1634 return m; 1635 } 1636 1637 static String[] splitString(String str, char sep) { 1638 int count = 1; 1639 int i = 0; 1640 while ((i=str.indexOf(sep, i)) >= 0) { 1641 count++; 1642 i++; 1643 } 1644 1645 String[] res = new String[count]; 1646 i=0; 1647 count = 0; 1648 int lastI=0; 1649 while ((i=str.indexOf(sep, i)) >= 0) { 1650 res[count] = str.substring(lastI, i); 1651 count++; 1652 i++; 1653 lastI = i; 1654 } 1655 res[count] = str.substring(lastI, str.length()); 1656 return res; 1657 } 1658 1659 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1660 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1661 Context.DISPLAY_SERVICE); 1662 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1663 } 1664 1665 public PackageManagerService(Context context, Installer installer, 1666 boolean factoryTest, boolean onlyCore) { 1667 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1668 SystemClock.uptimeMillis()); 1669 1670 if (mSdkVersion <= 0) { 1671 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1672 } 1673 1674 mContext = context; 1675 mFactoryTest = factoryTest; 1676 mOnlyCore = onlyCore; 1677 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1678 mMetrics = new DisplayMetrics(); 1679 mSettings = new Settings(mPackages); 1680 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1681 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1682 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1683 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1684 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1685 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1686 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1687 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1688 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1689 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1690 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1691 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1692 1693 // TODO: add a property to control this? 1694 long dexOptLRUThresholdInMinutes; 1695 if (mLazyDexOpt) { 1696 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1697 } else { 1698 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1699 } 1700 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1701 1702 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1703 if (separateProcesses != null && separateProcesses.length() > 0) { 1704 if ("*".equals(separateProcesses)) { 1705 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1706 mSeparateProcesses = null; 1707 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1708 } else { 1709 mDefParseFlags = 0; 1710 mSeparateProcesses = separateProcesses.split(","); 1711 Slog.w(TAG, "Running with debug.separate_processes: " 1712 + separateProcesses); 1713 } 1714 } else { 1715 mDefParseFlags = 0; 1716 mSeparateProcesses = null; 1717 } 1718 1719 mInstaller = installer; 1720 mPackageDexOptimizer = new PackageDexOptimizer(this); 1721 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 1722 1723 getDefaultDisplayMetrics(context, mMetrics); 1724 1725 SystemConfig systemConfig = SystemConfig.getInstance(); 1726 mGlobalGids = systemConfig.getGlobalGids(); 1727 mSystemPermissions = systemConfig.getSystemPermissions(); 1728 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1729 1730 synchronized (mInstallLock) { 1731 // writer 1732 synchronized (mPackages) { 1733 mHandlerThread = new ServiceThread(TAG, 1734 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1735 mHandlerThread.start(); 1736 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1737 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1738 1739 File dataDir = Environment.getDataDirectory(); 1740 mAppDataDir = new File(dataDir, "data"); 1741 mAppInstallDir = new File(dataDir, "app"); 1742 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1743 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1744 mUserAppDataDir = new File(dataDir, "user"); 1745 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1746 1747 sUserManager = new UserManagerService(context, this, 1748 mInstallLock, mPackages); 1749 1750 // Propagate permission configuration in to package manager. 1751 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1752 = systemConfig.getPermissions(); 1753 for (int i=0; i<permConfig.size(); i++) { 1754 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1755 BasePermission bp = mSettings.mPermissions.get(perm.name); 1756 if (bp == null) { 1757 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1758 mSettings.mPermissions.put(perm.name, bp); 1759 } 1760 if (perm.gids != null) { 1761 bp.setGids(perm.gids, perm.perUser); 1762 } 1763 } 1764 1765 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1766 for (int i=0; i<libConfig.size(); i++) { 1767 mSharedLibraries.put(libConfig.keyAt(i), 1768 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1769 } 1770 1771 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1772 1773 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1774 mSdkVersion, mOnlyCore); 1775 1776 String customResolverActivity = Resources.getSystem().getString( 1777 R.string.config_customResolverActivity); 1778 if (TextUtils.isEmpty(customResolverActivity)) { 1779 customResolverActivity = null; 1780 } else { 1781 mCustomResolverComponentName = ComponentName.unflattenFromString( 1782 customResolverActivity); 1783 } 1784 1785 long startTime = SystemClock.uptimeMillis(); 1786 1787 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1788 startTime); 1789 1790 // Set flag to monitor and not change apk file paths when 1791 // scanning install directories. 1792 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1793 1794 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1795 1796 /** 1797 * Add everything in the in the boot class path to the 1798 * list of process files because dexopt will have been run 1799 * if necessary during zygote startup. 1800 */ 1801 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1802 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1803 1804 if (bootClassPath != null) { 1805 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1806 for (String element : bootClassPathElements) { 1807 alreadyDexOpted.add(element); 1808 } 1809 } else { 1810 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1811 } 1812 1813 if (systemServerClassPath != null) { 1814 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1815 for (String element : systemServerClassPathElements) { 1816 alreadyDexOpted.add(element); 1817 } 1818 } else { 1819 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 1820 } 1821 1822 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 1823 final String[] dexCodeInstructionSets = 1824 getDexCodeInstructionSets( 1825 allInstructionSets.toArray(new String[allInstructionSets.size()])); 1826 1827 /** 1828 * Ensure all external libraries have had dexopt run on them. 1829 */ 1830 if (mSharedLibraries.size() > 0) { 1831 // NOTE: For now, we're compiling these system "shared libraries" 1832 // (and framework jars) into all available architectures. It's possible 1833 // to compile them only when we come across an app that uses them (there's 1834 // already logic for that in scanPackageLI) but that adds some complexity. 1835 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1836 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1837 final String lib = libEntry.path; 1838 if (lib == null) { 1839 continue; 1840 } 1841 1842 try { 1843 int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); 1844 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1845 alreadyDexOpted.add(lib); 1846 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 1847 } 1848 } catch (FileNotFoundException e) { 1849 Slog.w(TAG, "Library not found: " + lib); 1850 } catch (IOException e) { 1851 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1852 + e.getMessage()); 1853 } 1854 } 1855 } 1856 } 1857 1858 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1859 1860 // Gross hack for now: we know this file doesn't contain any 1861 // code, so don't dexopt it to avoid the resulting log spew. 1862 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1863 1864 // Gross hack for now: we know this file is only part of 1865 // the boot class path for art, so don't dexopt it to 1866 // avoid the resulting log spew. 1867 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1868 1869 /** 1870 * And there are a number of commands implemented in Java, which 1871 * we currently need to do the dexopt on so that they can be 1872 * run from a non-root shell. 1873 */ 1874 String[] frameworkFiles = frameworkDir.list(); 1875 if (frameworkFiles != null) { 1876 // TODO: We could compile these only for the most preferred ABI. We should 1877 // first double check that the dex files for these commands are not referenced 1878 // by other system apps. 1879 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1880 for (int i=0; i<frameworkFiles.length; i++) { 1881 File libPath = new File(frameworkDir, frameworkFiles[i]); 1882 String path = libPath.getPath(); 1883 // Skip the file if we already did it. 1884 if (alreadyDexOpted.contains(path)) { 1885 continue; 1886 } 1887 // Skip the file if it is not a type we want to dexopt. 1888 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1889 continue; 1890 } 1891 try { 1892 int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); 1893 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1894 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 1895 } 1896 } catch (FileNotFoundException e) { 1897 Slog.w(TAG, "Jar not found: " + path); 1898 } catch (IOException e) { 1899 Slog.w(TAG, "Exception reading jar: " + path, e); 1900 } 1901 } 1902 } 1903 } 1904 1905 // Collect vendor overlay packages. 1906 // (Do this before scanning any apps.) 1907 // For security and version matching reason, only consider 1908 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1909 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1910 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1911 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 1912 1913 // Find base frameworks (resource packages without code). 1914 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1915 | PackageParser.PARSE_IS_SYSTEM_DIR 1916 | PackageParser.PARSE_IS_PRIVILEGED, 1917 scanFlags | SCAN_NO_DEX, 0); 1918 1919 // Collected privileged system packages. 1920 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1921 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1922 | PackageParser.PARSE_IS_SYSTEM_DIR 1923 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 1924 1925 // Collect ordinary system packages. 1926 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1927 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1928 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1929 1930 // Collect all vendor packages. 1931 File vendorAppDir = new File("/vendor/app"); 1932 try { 1933 vendorAppDir = vendorAppDir.getCanonicalFile(); 1934 } catch (IOException e) { 1935 // failed to look up canonical path, continue with original one 1936 } 1937 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1938 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1939 1940 // Collect all OEM packages. 1941 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 1942 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 1943 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1944 1945 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1946 mInstaller.moveFiles(); 1947 1948 // Prune any system packages that no longer exist. 1949 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1950 final ArrayMap<String, File> expectingBetter = new ArrayMap<>(); 1951 if (!mOnlyCore) { 1952 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1953 while (psit.hasNext()) { 1954 PackageSetting ps = psit.next(); 1955 1956 /* 1957 * If this is not a system app, it can't be a 1958 * disable system app. 1959 */ 1960 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1961 continue; 1962 } 1963 1964 /* 1965 * If the package is scanned, it's not erased. 1966 */ 1967 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1968 if (scannedPkg != null) { 1969 /* 1970 * If the system app is both scanned and in the 1971 * disabled packages list, then it must have been 1972 * added via OTA. Remove it from the currently 1973 * scanned package so the previously user-installed 1974 * application can be scanned. 1975 */ 1976 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1977 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 1978 + ps.name + "; removing system app. Last known codePath=" 1979 + ps.codePathString + ", installStatus=" + ps.installStatus 1980 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 1981 + scannedPkg.mVersionCode); 1982 removePackageLI(ps, true); 1983 expectingBetter.put(ps.name, ps.codePath); 1984 } 1985 1986 continue; 1987 } 1988 1989 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 1990 psit.remove(); 1991 logCriticalInfo(Log.WARN, "System package " + ps.name 1992 + " no longer exists; wiping its data"); 1993 removeDataDirsLI(null, ps.name); 1994 } else { 1995 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 1996 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 1997 possiblyDeletedUpdatedSystemApps.add(ps.name); 1998 } 1999 } 2000 } 2001 } 2002 2003 //look for any incomplete package installations 2004 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2005 //clean up list 2006 for(int i = 0; i < deletePkgsList.size(); i++) { 2007 //clean up here 2008 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2009 } 2010 //delete tmp files 2011 deleteTempPackageFiles(); 2012 2013 // Remove any shared userIDs that have no associated packages 2014 mSettings.pruneSharedUsersLPw(); 2015 2016 if (!mOnlyCore) { 2017 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2018 SystemClock.uptimeMillis()); 2019 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2020 2021 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2022 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2023 2024 /** 2025 * Remove disable package settings for any updated system 2026 * apps that were removed via an OTA. If they're not a 2027 * previously-updated app, remove them completely. 2028 * Otherwise, just revoke their system-level permissions. 2029 */ 2030 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2031 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2032 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2033 2034 String msg; 2035 if (deletedPkg == null) { 2036 msg = "Updated system package " + deletedAppName 2037 + " no longer exists; wiping its data"; 2038 removeDataDirsLI(null, deletedAppName); 2039 } else { 2040 msg = "Updated system app + " + deletedAppName 2041 + " no longer present; removing system privileges for " 2042 + deletedAppName; 2043 2044 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2045 2046 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2047 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2048 } 2049 logCriticalInfo(Log.WARN, msg); 2050 } 2051 2052 /** 2053 * Make sure all system apps that we expected to appear on 2054 * the userdata partition actually showed up. If they never 2055 * appeared, crawl back and revive the system version. 2056 */ 2057 for (int i = 0; i < expectingBetter.size(); i++) { 2058 final String packageName = expectingBetter.keyAt(i); 2059 if (!mPackages.containsKey(packageName)) { 2060 final File scanFile = expectingBetter.valueAt(i); 2061 2062 logCriticalInfo(Log.WARN, "Expected better " + packageName 2063 + " but never showed up; reverting to system"); 2064 2065 final int reparseFlags; 2066 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2067 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2068 | PackageParser.PARSE_IS_SYSTEM_DIR 2069 | PackageParser.PARSE_IS_PRIVILEGED; 2070 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2071 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2072 | PackageParser.PARSE_IS_SYSTEM_DIR; 2073 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2074 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2075 | PackageParser.PARSE_IS_SYSTEM_DIR; 2076 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2077 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2078 | PackageParser.PARSE_IS_SYSTEM_DIR; 2079 } else { 2080 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2081 continue; 2082 } 2083 2084 mSettings.enableSystemPackageLPw(packageName); 2085 2086 try { 2087 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null); 2088 } catch (PackageManagerException e) { 2089 Slog.e(TAG, "Failed to parse original system package: " 2090 + e.getMessage()); 2091 } 2092 } 2093 } 2094 } 2095 2096 // Now that we know all of the shared libraries, update all clients to have 2097 // the correct library paths. 2098 updateAllSharedLibrariesLPw(); 2099 2100 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2101 // NOTE: We ignore potential failures here during a system scan (like 2102 // the rest of the commands above) because there's precious little we 2103 // can do about it. A settings error is reported, though. 2104 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2105 false /* force dexopt */, false /* defer dexopt */); 2106 } 2107 2108 // Now that we know all the packages we are keeping, 2109 // read and update their last usage times. 2110 mPackageUsage.readLP(); 2111 2112 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2113 SystemClock.uptimeMillis()); 2114 Slog.i(TAG, "Time to scan packages: " 2115 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2116 + " seconds"); 2117 2118 // If the platform SDK has changed since the last time we booted, 2119 // we need to re-grant app permission to catch any new ones that 2120 // appear. This is really a hack, and means that apps can in some 2121 // cases get permissions that the user didn't initially explicitly 2122 // allow... it would be nice to have some better way to handle 2123 // this situation. 2124 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 2125 != mSdkVersion; 2126 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 2127 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 2128 + "; regranting permissions for internal storage"); 2129 mSettings.mInternalSdkPlatform = mSdkVersion; 2130 2131 // For now runtime permissions are toggled via a system property. 2132 if (!RUNTIME_PERMISSIONS_ENABLED) { 2133 // Remove the runtime permissions state if the feature 2134 // was disabled by flipping the system property. 2135 mSettings.deleteRuntimePermissionsFiles(); 2136 } 2137 2138 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 2139 | (regrantPermissions 2140 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 2141 : 0)); 2142 2143 // If this is the first boot, and it is a normal boot, then 2144 // we need to initialize the default preferred apps. 2145 if (!mRestoredSettings && !onlyCore) { 2146 mSettings.readDefaultPreferredAppsLPw(this, 0); 2147 } 2148 2149 // If this is first boot after an OTA, and a normal boot, then 2150 // we need to clear code cache directories. 2151 mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint); 2152 if (mIsUpgrade && !onlyCore) { 2153 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2154 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2155 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2156 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2157 } 2158 mSettings.mFingerprint = Build.FINGERPRINT; 2159 } 2160 2161 // All the changes are done during package scanning. 2162 mSettings.updateInternalDatabaseVersion(); 2163 2164 // can downgrade to reader 2165 mSettings.writeLPr(); 2166 2167 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2168 SystemClock.uptimeMillis()); 2169 2170 mRequiredVerifierPackage = getRequiredVerifierLPr(); 2171 2172 mInstallerService = new PackageInstallerService(context, this); 2173 2174 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2175 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2176 mIntentFilterVerifierComponent); 2177 2178 primeDomainVerificationsLPw(false); 2179 2180 } // synchronized (mPackages) 2181 } // synchronized (mInstallLock) 2182 2183 // Now after opening every single application zip, make sure they 2184 // are all flushed. Not really needed, but keeps things nice and 2185 // tidy. 2186 Runtime.getRuntime().gc(); 2187 } 2188 2189 @Override 2190 public boolean isFirstBoot() { 2191 return !mRestoredSettings; 2192 } 2193 2194 @Override 2195 public boolean isOnlyCoreApps() { 2196 return mOnlyCore; 2197 } 2198 2199 @Override 2200 public boolean isUpgrade() { 2201 return mIsUpgrade; 2202 } 2203 2204 private String getRequiredVerifierLPr() { 2205 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2206 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2207 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 2208 2209 String requiredVerifier = null; 2210 2211 final int N = receivers.size(); 2212 for (int i = 0; i < N; i++) { 2213 final ResolveInfo info = receivers.get(i); 2214 2215 if (info.activityInfo == null) { 2216 continue; 2217 } 2218 2219 final String packageName = info.activityInfo.packageName; 2220 2221 if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 2222 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2223 continue; 2224 } 2225 2226 if (requiredVerifier != null) { 2227 throw new RuntimeException("There can be only one required verifier"); 2228 } 2229 2230 requiredVerifier = packageName; 2231 } 2232 2233 return requiredVerifier; 2234 } 2235 2236 private ComponentName getIntentFilterVerifierComponentNameLPr() { 2237 final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2238 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2239 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */); 2240 2241 ComponentName verifierComponentName = null; 2242 2243 int priority = -1000; 2244 final int N = receivers.size(); 2245 for (int i = 0; i < N; i++) { 2246 final ResolveInfo info = receivers.get(i); 2247 2248 if (info.activityInfo == null) { 2249 continue; 2250 } 2251 2252 final String packageName = info.activityInfo.packageName; 2253 2254 final PackageSetting ps = mSettings.mPackages.get(packageName); 2255 if (ps == null) { 2256 continue; 2257 } 2258 2259 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2260 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2261 continue; 2262 } 2263 2264 // Select the IntentFilterVerifier with the highest priority 2265 if (priority < info.priority) { 2266 priority = info.priority; 2267 verifierComponentName = new ComponentName(packageName, info.activityInfo.name); 2268 Slog.d(TAG, "Selecting IntentFilterVerifier: " + verifierComponentName + 2269 " with priority: " + info.priority); 2270 } 2271 } 2272 2273 return verifierComponentName; 2274 } 2275 2276 private void primeDomainVerificationsLPw(boolean logging) { 2277 Slog.d(TAG, "Start priming domain verification"); 2278 boolean updated = false; 2279 ArrayList<String> allHosts = new ArrayList<>(); 2280 for (PackageParser.Package pkg : mPackages.values()) { 2281 final String packageName = pkg.packageName; 2282 if (!hasDomainURLs(pkg)) { 2283 if (logging) { 2284 Slog.d(TAG, "No priming domain verifications for " + 2285 "package with no domain URLs: " + packageName); 2286 } 2287 continue; 2288 } 2289 if (!pkg.isSystemApp()) { 2290 if (logging) { 2291 Slog.d(TAG, "No priming domain verifications for a non system package : " + 2292 packageName); 2293 } 2294 continue; 2295 } 2296 for (PackageParser.Activity a : pkg.activities) { 2297 for (ActivityIntentInfo filter : a.intents) { 2298 if (hasValidDomains(filter, false)) { 2299 allHosts.addAll(filter.getHostsList()); 2300 } 2301 } 2302 } 2303 if (allHosts.size() == 0) { 2304 allHosts.add("*"); 2305 } 2306 IntentFilterVerificationInfo ivi = 2307 mSettings.createIntentFilterVerificationIfNeededLPw(packageName, allHosts); 2308 if (ivi != null) { 2309 // We will always log this 2310 Slog.d(TAG, "Priming domain verifications for package: " + packageName); 2311 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 2312 updated = true; 2313 } 2314 else { 2315 if (logging) { 2316 Slog.d(TAG, "No priming domain verifications for package: " + packageName); 2317 } 2318 } 2319 allHosts.clear(); 2320 } 2321 if (updated) { 2322 scheduleWriteSettingsLocked(); 2323 } 2324 Slog.d(TAG, "End priming domain verification"); 2325 } 2326 2327 @Override 2328 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2329 throws RemoteException { 2330 try { 2331 return super.onTransact(code, data, reply, flags); 2332 } catch (RuntimeException e) { 2333 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2334 Slog.wtf(TAG, "Package Manager Crash", e); 2335 } 2336 throw e; 2337 } 2338 } 2339 2340 void cleanupInstallFailedPackage(PackageSetting ps) { 2341 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2342 2343 removeDataDirsLI(ps.volumeUuid, ps.name); 2344 if (ps.codePath != null) { 2345 if (ps.codePath.isDirectory()) { 2346 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath()); 2347 } else { 2348 ps.codePath.delete(); 2349 } 2350 } 2351 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2352 if (ps.resourcePath.isDirectory()) { 2353 FileUtils.deleteContents(ps.resourcePath); 2354 } 2355 ps.resourcePath.delete(); 2356 } 2357 mSettings.removePackageLPw(ps.name); 2358 } 2359 2360 static int[] appendInts(int[] cur, int[] add) { 2361 if (add == null) return cur; 2362 if (cur == null) return add; 2363 final int N = add.length; 2364 for (int i=0; i<N; i++) { 2365 cur = appendInt(cur, add[i]); 2366 } 2367 return cur; 2368 } 2369 2370 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2371 if (!sUserManager.exists(userId)) return null; 2372 final PackageSetting ps = (PackageSetting) p.mExtras; 2373 if (ps == null) { 2374 return null; 2375 } 2376 2377 final PermissionsState permissionsState = ps.getPermissionsState(); 2378 2379 final int[] gids = permissionsState.computeGids(userId); 2380 final Set<String> permissions = permissionsState.getPermissions(userId); 2381 final PackageUserState state = ps.readUserState(userId); 2382 2383 return PackageParser.generatePackageInfo(p, gids, flags, 2384 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2385 } 2386 2387 @Override 2388 public boolean isPackageFrozen(String packageName) { 2389 synchronized (mPackages) { 2390 final PackageSetting ps = mSettings.mPackages.get(packageName); 2391 if (ps != null) { 2392 return ps.frozen; 2393 } 2394 } 2395 Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen"); 2396 return true; 2397 } 2398 2399 @Override 2400 public boolean isPackageAvailable(String packageName, int userId) { 2401 if (!sUserManager.exists(userId)) return false; 2402 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 2403 synchronized (mPackages) { 2404 PackageParser.Package p = mPackages.get(packageName); 2405 if (p != null) { 2406 final PackageSetting ps = (PackageSetting) p.mExtras; 2407 if (ps != null) { 2408 final PackageUserState state = ps.readUserState(userId); 2409 if (state != null) { 2410 return PackageParser.isAvailable(state); 2411 } 2412 } 2413 } 2414 } 2415 return false; 2416 } 2417 2418 @Override 2419 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2420 if (!sUserManager.exists(userId)) return null; 2421 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 2422 // reader 2423 synchronized (mPackages) { 2424 PackageParser.Package p = mPackages.get(packageName); 2425 if (DEBUG_PACKAGE_INFO) 2426 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2427 if (p != null) { 2428 return generatePackageInfo(p, flags, userId); 2429 } 2430 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2431 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2432 } 2433 } 2434 return null; 2435 } 2436 2437 @Override 2438 public String[] currentToCanonicalPackageNames(String[] names) { 2439 String[] out = new String[names.length]; 2440 // reader 2441 synchronized (mPackages) { 2442 for (int i=names.length-1; i>=0; i--) { 2443 PackageSetting ps = mSettings.mPackages.get(names[i]); 2444 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2445 } 2446 } 2447 return out; 2448 } 2449 2450 @Override 2451 public String[] canonicalToCurrentPackageNames(String[] names) { 2452 String[] out = new String[names.length]; 2453 // reader 2454 synchronized (mPackages) { 2455 for (int i=names.length-1; i>=0; i--) { 2456 String cur = mSettings.mRenamedPackages.get(names[i]); 2457 out[i] = cur != null ? cur : names[i]; 2458 } 2459 } 2460 return out; 2461 } 2462 2463 @Override 2464 public int getPackageUid(String packageName, int userId) { 2465 if (!sUserManager.exists(userId)) return -1; 2466 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 2467 2468 // reader 2469 synchronized (mPackages) { 2470 PackageParser.Package p = mPackages.get(packageName); 2471 if(p != null) { 2472 return UserHandle.getUid(userId, p.applicationInfo.uid); 2473 } 2474 PackageSetting ps = mSettings.mPackages.get(packageName); 2475 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 2476 return -1; 2477 } 2478 p = ps.pkg; 2479 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 2480 } 2481 } 2482 2483 @Override 2484 public int[] getPackageGids(String packageName, int userId) throws RemoteException { 2485 if (!sUserManager.exists(userId)) { 2486 return null; 2487 } 2488 2489 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 2490 "getPackageGids"); 2491 2492 // reader 2493 synchronized (mPackages) { 2494 PackageParser.Package p = mPackages.get(packageName); 2495 if (DEBUG_PACKAGE_INFO) { 2496 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 2497 } 2498 if (p != null) { 2499 PackageSetting ps = (PackageSetting) p.mExtras; 2500 return ps.getPermissionsState().computeGids(userId); 2501 } 2502 } 2503 2504 return null; 2505 } 2506 2507 static PermissionInfo generatePermissionInfo( 2508 BasePermission bp, int flags) { 2509 if (bp.perm != null) { 2510 return PackageParser.generatePermissionInfo(bp.perm, flags); 2511 } 2512 PermissionInfo pi = new PermissionInfo(); 2513 pi.name = bp.name; 2514 pi.packageName = bp.sourcePackage; 2515 pi.nonLocalizedLabel = bp.name; 2516 pi.protectionLevel = bp.protectionLevel; 2517 return pi; 2518 } 2519 2520 @Override 2521 public PermissionInfo getPermissionInfo(String name, int flags) { 2522 // reader 2523 synchronized (mPackages) { 2524 final BasePermission p = mSettings.mPermissions.get(name); 2525 if (p != null) { 2526 return generatePermissionInfo(p, flags); 2527 } 2528 return null; 2529 } 2530 } 2531 2532 @Override 2533 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2534 // reader 2535 synchronized (mPackages) { 2536 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2537 for (BasePermission p : mSettings.mPermissions.values()) { 2538 if (group == null) { 2539 if (p.perm == null || p.perm.info.group == null) { 2540 out.add(generatePermissionInfo(p, flags)); 2541 } 2542 } else { 2543 if (p.perm != null && group.equals(p.perm.info.group)) { 2544 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2545 } 2546 } 2547 } 2548 2549 if (out.size() > 0) { 2550 return out; 2551 } 2552 return mPermissionGroups.containsKey(group) ? out : null; 2553 } 2554 } 2555 2556 @Override 2557 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2558 // reader 2559 synchronized (mPackages) { 2560 return PackageParser.generatePermissionGroupInfo( 2561 mPermissionGroups.get(name), flags); 2562 } 2563 } 2564 2565 @Override 2566 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2567 // reader 2568 synchronized (mPackages) { 2569 final int N = mPermissionGroups.size(); 2570 ArrayList<PermissionGroupInfo> out 2571 = new ArrayList<PermissionGroupInfo>(N); 2572 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2573 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2574 } 2575 return out; 2576 } 2577 } 2578 2579 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2580 int userId) { 2581 if (!sUserManager.exists(userId)) return null; 2582 PackageSetting ps = mSettings.mPackages.get(packageName); 2583 if (ps != null) { 2584 if (ps.pkg == null) { 2585 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2586 flags, userId); 2587 if (pInfo != null) { 2588 return pInfo.applicationInfo; 2589 } 2590 return null; 2591 } 2592 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2593 ps.readUserState(userId), userId); 2594 } 2595 return null; 2596 } 2597 2598 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2599 int userId) { 2600 if (!sUserManager.exists(userId)) return null; 2601 PackageSetting ps = mSettings.mPackages.get(packageName); 2602 if (ps != null) { 2603 PackageParser.Package pkg = ps.pkg; 2604 if (pkg == null) { 2605 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2606 return null; 2607 } 2608 // Only data remains, so we aren't worried about code paths 2609 pkg = new PackageParser.Package(packageName); 2610 pkg.applicationInfo.packageName = packageName; 2611 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2612 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 2613 pkg.applicationInfo.dataDir = PackageManager.getDataDirForUser(ps.volumeUuid, 2614 packageName, userId).getAbsolutePath(); 2615 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2616 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2617 } 2618 return generatePackageInfo(pkg, flags, userId); 2619 } 2620 return null; 2621 } 2622 2623 @Override 2624 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2625 if (!sUserManager.exists(userId)) return null; 2626 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2627 // writer 2628 synchronized (mPackages) { 2629 PackageParser.Package p = mPackages.get(packageName); 2630 if (DEBUG_PACKAGE_INFO) Log.v( 2631 TAG, "getApplicationInfo " + packageName 2632 + ": " + p); 2633 if (p != null) { 2634 PackageSetting ps = mSettings.mPackages.get(packageName); 2635 if (ps == null) return null; 2636 // Note: isEnabledLP() does not apply here - always return info 2637 return PackageParser.generateApplicationInfo( 2638 p, flags, ps.readUserState(userId), userId); 2639 } 2640 if ("android".equals(packageName)||"system".equals(packageName)) { 2641 return mAndroidApplication; 2642 } 2643 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2644 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2645 } 2646 } 2647 return null; 2648 } 2649 2650 @Override 2651 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 2652 final IPackageDataObserver observer) { 2653 mContext.enforceCallingOrSelfPermission( 2654 android.Manifest.permission.CLEAR_APP_CACHE, null); 2655 // Queue up an async operation since clearing cache may take a little while. 2656 mHandler.post(new Runnable() { 2657 public void run() { 2658 mHandler.removeCallbacks(this); 2659 int retCode = -1; 2660 synchronized (mInstallLock) { 2661 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2662 if (retCode < 0) { 2663 Slog.w(TAG, "Couldn't clear application caches"); 2664 } 2665 } 2666 if (observer != null) { 2667 try { 2668 observer.onRemoveCompleted(null, (retCode >= 0)); 2669 } catch (RemoteException e) { 2670 Slog.w(TAG, "RemoveException when invoking call back"); 2671 } 2672 } 2673 } 2674 }); 2675 } 2676 2677 @Override 2678 public void freeStorage(final String volumeUuid, final long freeStorageSize, 2679 final IntentSender pi) { 2680 mContext.enforceCallingOrSelfPermission( 2681 android.Manifest.permission.CLEAR_APP_CACHE, null); 2682 // Queue up an async operation since clearing cache may take a little while. 2683 mHandler.post(new Runnable() { 2684 public void run() { 2685 mHandler.removeCallbacks(this); 2686 int retCode = -1; 2687 synchronized (mInstallLock) { 2688 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2689 if (retCode < 0) { 2690 Slog.w(TAG, "Couldn't clear application caches"); 2691 } 2692 } 2693 if(pi != null) { 2694 try { 2695 // Callback via pending intent 2696 int code = (retCode >= 0) ? 1 : 0; 2697 pi.sendIntent(null, code, null, 2698 null, null); 2699 } catch (SendIntentException e1) { 2700 Slog.i(TAG, "Failed to send pending intent"); 2701 } 2702 } 2703 } 2704 }); 2705 } 2706 2707 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 2708 synchronized (mInstallLock) { 2709 if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) { 2710 throw new IOException("Failed to free enough space"); 2711 } 2712 } 2713 } 2714 2715 @Override 2716 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2717 if (!sUserManager.exists(userId)) return null; 2718 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 2719 synchronized (mPackages) { 2720 PackageParser.Activity a = mActivities.mActivities.get(component); 2721 2722 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2723 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2724 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2725 if (ps == null) return null; 2726 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2727 userId); 2728 } 2729 if (mResolveComponentName.equals(component)) { 2730 return PackageParser.generateActivityInfo(mResolveActivity, flags, 2731 new PackageUserState(), userId); 2732 } 2733 } 2734 return null; 2735 } 2736 2737 @Override 2738 public boolean activitySupportsIntent(ComponentName component, Intent intent, 2739 String resolvedType) { 2740 synchronized (mPackages) { 2741 PackageParser.Activity a = mActivities.mActivities.get(component); 2742 if (a == null) { 2743 return false; 2744 } 2745 for (int i=0; i<a.intents.size(); i++) { 2746 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 2747 intent.getData(), intent.getCategories(), TAG) >= 0) { 2748 return true; 2749 } 2750 } 2751 return false; 2752 } 2753 } 2754 2755 @Override 2756 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2757 if (!sUserManager.exists(userId)) return null; 2758 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 2759 synchronized (mPackages) { 2760 PackageParser.Activity a = mReceivers.mActivities.get(component); 2761 if (DEBUG_PACKAGE_INFO) Log.v( 2762 TAG, "getReceiverInfo " + component + ": " + a); 2763 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2764 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2765 if (ps == null) return null; 2766 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2767 userId); 2768 } 2769 } 2770 return null; 2771 } 2772 2773 @Override 2774 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2775 if (!sUserManager.exists(userId)) return null; 2776 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 2777 synchronized (mPackages) { 2778 PackageParser.Service s = mServices.mServices.get(component); 2779 if (DEBUG_PACKAGE_INFO) Log.v( 2780 TAG, "getServiceInfo " + component + ": " + s); 2781 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2782 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2783 if (ps == null) return null; 2784 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2785 userId); 2786 } 2787 } 2788 return null; 2789 } 2790 2791 @Override 2792 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2793 if (!sUserManager.exists(userId)) return null; 2794 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 2795 synchronized (mPackages) { 2796 PackageParser.Provider p = mProviders.mProviders.get(component); 2797 if (DEBUG_PACKAGE_INFO) Log.v( 2798 TAG, "getProviderInfo " + component + ": " + p); 2799 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2800 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2801 if (ps == null) return null; 2802 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2803 userId); 2804 } 2805 } 2806 return null; 2807 } 2808 2809 @Override 2810 public String[] getSystemSharedLibraryNames() { 2811 Set<String> libSet; 2812 synchronized (mPackages) { 2813 libSet = mSharedLibraries.keySet(); 2814 int size = libSet.size(); 2815 if (size > 0) { 2816 String[] libs = new String[size]; 2817 libSet.toArray(libs); 2818 return libs; 2819 } 2820 } 2821 return null; 2822 } 2823 2824 /** 2825 * @hide 2826 */ 2827 PackageParser.Package findSharedNonSystemLibrary(String libName) { 2828 synchronized (mPackages) { 2829 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 2830 if (lib != null && lib.apk != null) { 2831 return mPackages.get(lib.apk); 2832 } 2833 } 2834 return null; 2835 } 2836 2837 @Override 2838 public FeatureInfo[] getSystemAvailableFeatures() { 2839 Collection<FeatureInfo> featSet; 2840 synchronized (mPackages) { 2841 featSet = mAvailableFeatures.values(); 2842 int size = featSet.size(); 2843 if (size > 0) { 2844 FeatureInfo[] features = new FeatureInfo[size+1]; 2845 featSet.toArray(features); 2846 FeatureInfo fi = new FeatureInfo(); 2847 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2848 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2849 features[size] = fi; 2850 return features; 2851 } 2852 } 2853 return null; 2854 } 2855 2856 @Override 2857 public boolean hasSystemFeature(String name) { 2858 synchronized (mPackages) { 2859 return mAvailableFeatures.containsKey(name); 2860 } 2861 } 2862 2863 private void checkValidCaller(int uid, int userId) { 2864 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2865 return; 2866 2867 throw new SecurityException("Caller uid=" + uid 2868 + " is not privileged to communicate with user=" + userId); 2869 } 2870 2871 @Override 2872 public int checkPermission(String permName, String pkgName, int userId) { 2873 if (!sUserManager.exists(userId)) { 2874 return PackageManager.PERMISSION_DENIED; 2875 } 2876 2877 synchronized (mPackages) { 2878 final PackageParser.Package p = mPackages.get(pkgName); 2879 if (p != null && p.mExtras != null) { 2880 final PackageSetting ps = (PackageSetting) p.mExtras; 2881 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2882 return PackageManager.PERMISSION_GRANTED; 2883 } 2884 } 2885 } 2886 2887 return PackageManager.PERMISSION_DENIED; 2888 } 2889 2890 @Override 2891 public int checkUidPermission(String permName, int uid) { 2892 final int userId = UserHandle.getUserId(uid); 2893 2894 if (!sUserManager.exists(userId)) { 2895 return PackageManager.PERMISSION_DENIED; 2896 } 2897 2898 synchronized (mPackages) { 2899 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2900 if (obj != null) { 2901 final SettingBase ps = (SettingBase) obj; 2902 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2903 return PackageManager.PERMISSION_GRANTED; 2904 } 2905 } else { 2906 ArraySet<String> perms = mSystemPermissions.get(uid); 2907 if (perms != null && perms.contains(permName)) { 2908 return PackageManager.PERMISSION_GRANTED; 2909 } 2910 } 2911 } 2912 2913 return PackageManager.PERMISSION_DENIED; 2914 } 2915 2916 /** 2917 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2918 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2919 * @param checkShell TODO(yamasani): 2920 * @param message the message to log on security exception 2921 */ 2922 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 2923 boolean checkShell, String message) { 2924 if (userId < 0) { 2925 throw new IllegalArgumentException("Invalid userId " + userId); 2926 } 2927 if (checkShell) { 2928 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 2929 } 2930 if (userId == UserHandle.getUserId(callingUid)) return; 2931 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2932 if (requireFullPermission) { 2933 mContext.enforceCallingOrSelfPermission( 2934 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2935 } else { 2936 try { 2937 mContext.enforceCallingOrSelfPermission( 2938 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2939 } catch (SecurityException se) { 2940 mContext.enforceCallingOrSelfPermission( 2941 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2942 } 2943 } 2944 } 2945 } 2946 2947 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 2948 if (callingUid == Process.SHELL_UID) { 2949 if (userHandle >= 0 2950 && sUserManager.hasUserRestriction(restriction, userHandle)) { 2951 throw new SecurityException("Shell does not have permission to access user " 2952 + userHandle); 2953 } else if (userHandle < 0) { 2954 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 2955 + Debug.getCallers(3)); 2956 } 2957 } 2958 } 2959 2960 private BasePermission findPermissionTreeLP(String permName) { 2961 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2962 if (permName.startsWith(bp.name) && 2963 permName.length() > bp.name.length() && 2964 permName.charAt(bp.name.length()) == '.') { 2965 return bp; 2966 } 2967 } 2968 return null; 2969 } 2970 2971 private BasePermission checkPermissionTreeLP(String permName) { 2972 if (permName != null) { 2973 BasePermission bp = findPermissionTreeLP(permName); 2974 if (bp != null) { 2975 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2976 return bp; 2977 } 2978 throw new SecurityException("Calling uid " 2979 + Binder.getCallingUid() 2980 + " is not allowed to add to permission tree " 2981 + bp.name + " owned by uid " + bp.uid); 2982 } 2983 } 2984 throw new SecurityException("No permission tree found for " + permName); 2985 } 2986 2987 static boolean compareStrings(CharSequence s1, CharSequence s2) { 2988 if (s1 == null) { 2989 return s2 == null; 2990 } 2991 if (s2 == null) { 2992 return false; 2993 } 2994 if (s1.getClass() != s2.getClass()) { 2995 return false; 2996 } 2997 return s1.equals(s2); 2998 } 2999 3000 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3001 if (pi1.icon != pi2.icon) return false; 3002 if (pi1.logo != pi2.logo) return false; 3003 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3004 if (!compareStrings(pi1.name, pi2.name)) return false; 3005 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3006 // We'll take care of setting this one. 3007 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3008 // These are not currently stored in settings. 3009 //if (!compareStrings(pi1.group, pi2.group)) return false; 3010 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3011 //if (pi1.labelRes != pi2.labelRes) return false; 3012 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3013 return true; 3014 } 3015 3016 int permissionInfoFootprint(PermissionInfo info) { 3017 int size = info.name.length(); 3018 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3019 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3020 return size; 3021 } 3022 3023 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3024 int size = 0; 3025 for (BasePermission perm : mSettings.mPermissions.values()) { 3026 if (perm.uid == tree.uid) { 3027 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3028 } 3029 } 3030 return size; 3031 } 3032 3033 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3034 // We calculate the max size of permissions defined by this uid and throw 3035 // if that plus the size of 'info' would exceed our stated maximum. 3036 if (tree.uid != Process.SYSTEM_UID) { 3037 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3038 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3039 throw new SecurityException("Permission tree size cap exceeded"); 3040 } 3041 } 3042 } 3043 3044 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3045 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3046 throw new SecurityException("Label must be specified in permission"); 3047 } 3048 BasePermission tree = checkPermissionTreeLP(info.name); 3049 BasePermission bp = mSettings.mPermissions.get(info.name); 3050 boolean added = bp == null; 3051 boolean changed = true; 3052 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3053 if (added) { 3054 enforcePermissionCapLocked(info, tree); 3055 bp = new BasePermission(info.name, tree.sourcePackage, 3056 BasePermission.TYPE_DYNAMIC); 3057 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3058 throw new SecurityException( 3059 "Not allowed to modify non-dynamic permission " 3060 + info.name); 3061 } else { 3062 if (bp.protectionLevel == fixedLevel 3063 && bp.perm.owner.equals(tree.perm.owner) 3064 && bp.uid == tree.uid 3065 && comparePermissionInfos(bp.perm.info, info)) { 3066 changed = false; 3067 } 3068 } 3069 bp.protectionLevel = fixedLevel; 3070 info = new PermissionInfo(info); 3071 info.protectionLevel = fixedLevel; 3072 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3073 bp.perm.info.packageName = tree.perm.info.packageName; 3074 bp.uid = tree.uid; 3075 if (added) { 3076 mSettings.mPermissions.put(info.name, bp); 3077 } 3078 if (changed) { 3079 if (!async) { 3080 mSettings.writeLPr(); 3081 } else { 3082 scheduleWriteSettingsLocked(); 3083 } 3084 } 3085 return added; 3086 } 3087 3088 @Override 3089 public boolean addPermission(PermissionInfo info) { 3090 synchronized (mPackages) { 3091 return addPermissionLocked(info, false); 3092 } 3093 } 3094 3095 @Override 3096 public boolean addPermissionAsync(PermissionInfo info) { 3097 synchronized (mPackages) { 3098 return addPermissionLocked(info, true); 3099 } 3100 } 3101 3102 @Override 3103 public void removePermission(String name) { 3104 synchronized (mPackages) { 3105 checkPermissionTreeLP(name); 3106 BasePermission bp = mSettings.mPermissions.get(name); 3107 if (bp != null) { 3108 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3109 throw new SecurityException( 3110 "Not allowed to modify non-dynamic permission " 3111 + name); 3112 } 3113 mSettings.mPermissions.remove(name); 3114 mSettings.writeLPr(); 3115 } 3116 } 3117 } 3118 3119 private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg, 3120 BasePermission bp) { 3121 int index = pkg.requestedPermissions.indexOf(bp.name); 3122 if (index == -1) { 3123 throw new SecurityException("Package " + pkg.packageName 3124 + " has not requested permission " + bp.name); 3125 } 3126 if (!bp.isRuntime()) { 3127 throw new SecurityException("Permission " + bp.name 3128 + " is not a changeable permission type"); 3129 } 3130 } 3131 3132 @Override 3133 public boolean grantPermission(String packageName, String name, int userId) { 3134 if (!RUNTIME_PERMISSIONS_ENABLED) { 3135 return false; 3136 } 3137 3138 if (!sUserManager.exists(userId)) { 3139 return false; 3140 } 3141 3142 mContext.enforceCallingOrSelfPermission( 3143 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3144 "grantPermission"); 3145 3146 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3147 "grantPermission"); 3148 3149 boolean gidsChanged = false; 3150 final SettingBase sb; 3151 3152 synchronized (mPackages) { 3153 final PackageParser.Package pkg = mPackages.get(packageName); 3154 if (pkg == null) { 3155 throw new IllegalArgumentException("Unknown package: " + packageName); 3156 } 3157 3158 final BasePermission bp = mSettings.mPermissions.get(name); 3159 if (bp == null) { 3160 throw new IllegalArgumentException("Unknown permission: " + name); 3161 } 3162 3163 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3164 3165 sb = (SettingBase) pkg.mExtras; 3166 if (sb == null) { 3167 throw new IllegalArgumentException("Unknown package: " + packageName); 3168 } 3169 3170 final PermissionsState permissionsState = sb.getPermissionsState(); 3171 3172 final int result = permissionsState.grantRuntimePermission(bp, userId); 3173 switch (result) { 3174 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3175 return false; 3176 } 3177 3178 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3179 gidsChanged = true; 3180 } break; 3181 } 3182 3183 // Not critical if that is lost - app has to request again. 3184 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3185 } 3186 3187 if (gidsChanged) { 3188 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED); 3189 } 3190 3191 return true; 3192 } 3193 3194 @Override 3195 public boolean revokePermission(String packageName, String name, int userId) { 3196 if (!RUNTIME_PERMISSIONS_ENABLED) { 3197 return false; 3198 } 3199 3200 if (!sUserManager.exists(userId)) { 3201 return false; 3202 } 3203 3204 mContext.enforceCallingOrSelfPermission( 3205 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3206 "revokePermission"); 3207 3208 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3209 "revokePermission"); 3210 3211 final SettingBase sb; 3212 3213 synchronized (mPackages) { 3214 final PackageParser.Package pkg = mPackages.get(packageName); 3215 if (pkg == null) { 3216 throw new IllegalArgumentException("Unknown package: " + packageName); 3217 } 3218 3219 final BasePermission bp = mSettings.mPermissions.get(name); 3220 if (bp == null) { 3221 throw new IllegalArgumentException("Unknown permission: " + name); 3222 } 3223 3224 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3225 3226 sb = (SettingBase) pkg.mExtras; 3227 if (sb == null) { 3228 throw new IllegalArgumentException("Unknown package: " + packageName); 3229 } 3230 3231 final PermissionsState permissionsState = sb.getPermissionsState(); 3232 3233 if (permissionsState.revokeRuntimePermission(bp, userId) == 3234 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3235 return false; 3236 } 3237 3238 // Critical, after this call all should never have the permission. 3239 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3240 } 3241 3242 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 3243 3244 return true; 3245 } 3246 3247 @Override 3248 public boolean isProtectedBroadcast(String actionName) { 3249 synchronized (mPackages) { 3250 return mProtectedBroadcasts.contains(actionName); 3251 } 3252 } 3253 3254 @Override 3255 public int checkSignatures(String pkg1, String pkg2) { 3256 synchronized (mPackages) { 3257 final PackageParser.Package p1 = mPackages.get(pkg1); 3258 final PackageParser.Package p2 = mPackages.get(pkg2); 3259 if (p1 == null || p1.mExtras == null 3260 || p2 == null || p2.mExtras == null) { 3261 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3262 } 3263 return compareSignatures(p1.mSignatures, p2.mSignatures); 3264 } 3265 } 3266 3267 @Override 3268 public int checkUidSignatures(int uid1, int uid2) { 3269 // Map to base uids. 3270 uid1 = UserHandle.getAppId(uid1); 3271 uid2 = UserHandle.getAppId(uid2); 3272 // reader 3273 synchronized (mPackages) { 3274 Signature[] s1; 3275 Signature[] s2; 3276 Object obj = mSettings.getUserIdLPr(uid1); 3277 if (obj != null) { 3278 if (obj instanceof SharedUserSetting) { 3279 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 3280 } else if (obj instanceof PackageSetting) { 3281 s1 = ((PackageSetting)obj).signatures.mSignatures; 3282 } else { 3283 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3284 } 3285 } else { 3286 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3287 } 3288 obj = mSettings.getUserIdLPr(uid2); 3289 if (obj != null) { 3290 if (obj instanceof SharedUserSetting) { 3291 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 3292 } else if (obj instanceof PackageSetting) { 3293 s2 = ((PackageSetting)obj).signatures.mSignatures; 3294 } else { 3295 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3296 } 3297 } else { 3298 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3299 } 3300 return compareSignatures(s1, s2); 3301 } 3302 } 3303 3304 private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) { 3305 final long identity = Binder.clearCallingIdentity(); 3306 try { 3307 if (sb instanceof SharedUserSetting) { 3308 SharedUserSetting sus = (SharedUserSetting) sb; 3309 final int packageCount = sus.packages.size(); 3310 for (int i = 0; i < packageCount; i++) { 3311 PackageSetting susPs = sus.packages.valueAt(i); 3312 if (userId == UserHandle.USER_ALL) { 3313 killApplication(susPs.pkg.packageName, susPs.appId, reason); 3314 } else { 3315 final int uid = UserHandle.getUid(userId, susPs.appId); 3316 killUid(uid, reason); 3317 } 3318 } 3319 } else if (sb instanceof PackageSetting) { 3320 PackageSetting ps = (PackageSetting) sb; 3321 if (userId == UserHandle.USER_ALL) { 3322 killApplication(ps.pkg.packageName, ps.appId, reason); 3323 } else { 3324 final int uid = UserHandle.getUid(userId, ps.appId); 3325 killUid(uid, reason); 3326 } 3327 } 3328 } finally { 3329 Binder.restoreCallingIdentity(identity); 3330 } 3331 } 3332 3333 private static void killUid(int uid, String reason) { 3334 IActivityManager am = ActivityManagerNative.getDefault(); 3335 if (am != null) { 3336 try { 3337 am.killUid(uid, reason); 3338 } catch (RemoteException e) { 3339 /* ignore - same process */ 3340 } 3341 } 3342 } 3343 3344 /** 3345 * Compares two sets of signatures. Returns: 3346 * <br /> 3347 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 3348 * <br /> 3349 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 3350 * <br /> 3351 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 3352 * <br /> 3353 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 3354 * <br /> 3355 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 3356 */ 3357 static int compareSignatures(Signature[] s1, Signature[] s2) { 3358 if (s1 == null) { 3359 return s2 == null 3360 ? PackageManager.SIGNATURE_NEITHER_SIGNED 3361 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 3362 } 3363 3364 if (s2 == null) { 3365 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 3366 } 3367 3368 if (s1.length != s2.length) { 3369 return PackageManager.SIGNATURE_NO_MATCH; 3370 } 3371 3372 // Since both signature sets are of size 1, we can compare without HashSets. 3373 if (s1.length == 1) { 3374 return s1[0].equals(s2[0]) ? 3375 PackageManager.SIGNATURE_MATCH : 3376 PackageManager.SIGNATURE_NO_MATCH; 3377 } 3378 3379 ArraySet<Signature> set1 = new ArraySet<Signature>(); 3380 for (Signature sig : s1) { 3381 set1.add(sig); 3382 } 3383 ArraySet<Signature> set2 = new ArraySet<Signature>(); 3384 for (Signature sig : s2) { 3385 set2.add(sig); 3386 } 3387 // Make sure s2 contains all signatures in s1. 3388 if (set1.equals(set2)) { 3389 return PackageManager.SIGNATURE_MATCH; 3390 } 3391 return PackageManager.SIGNATURE_NO_MATCH; 3392 } 3393 3394 /** 3395 * If the database version for this type of package (internal storage or 3396 * external storage) is less than the version where package signatures 3397 * were updated, return true. 3398 */ 3399 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3400 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan( 3401 DatabaseVersion.SIGNATURE_END_ENTITY)) 3402 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan( 3403 DatabaseVersion.SIGNATURE_END_ENTITY)); 3404 } 3405 3406 /** 3407 * Used for backward compatibility to make sure any packages with 3408 * certificate chains get upgraded to the new style. {@code existingSigs} 3409 * will be in the old format (since they were stored on disk from before the 3410 * system upgrade) and {@code scannedSigs} will be in the newer format. 3411 */ 3412 private int compareSignaturesCompat(PackageSignatures existingSigs, 3413 PackageParser.Package scannedPkg) { 3414 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 3415 return PackageManager.SIGNATURE_NO_MATCH; 3416 } 3417 3418 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 3419 for (Signature sig : existingSigs.mSignatures) { 3420 existingSet.add(sig); 3421 } 3422 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 3423 for (Signature sig : scannedPkg.mSignatures) { 3424 try { 3425 Signature[] chainSignatures = sig.getChainSignatures(); 3426 for (Signature chainSig : chainSignatures) { 3427 scannedCompatSet.add(chainSig); 3428 } 3429 } catch (CertificateEncodingException e) { 3430 scannedCompatSet.add(sig); 3431 } 3432 } 3433 /* 3434 * Make sure the expanded scanned set contains all signatures in the 3435 * existing one. 3436 */ 3437 if (scannedCompatSet.equals(existingSet)) { 3438 // Migrate the old signatures to the new scheme. 3439 existingSigs.assignSignatures(scannedPkg.mSignatures); 3440 // The new KeySets will be re-added later in the scanning process. 3441 synchronized (mPackages) { 3442 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 3443 } 3444 return PackageManager.SIGNATURE_MATCH; 3445 } 3446 return PackageManager.SIGNATURE_NO_MATCH; 3447 } 3448 3449 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3450 if (isExternal(scannedPkg)) { 3451 return mSettings.isExternalDatabaseVersionOlderThan( 3452 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3453 } else { 3454 return mSettings.isInternalDatabaseVersionOlderThan( 3455 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3456 } 3457 } 3458 3459 private int compareSignaturesRecover(PackageSignatures existingSigs, 3460 PackageParser.Package scannedPkg) { 3461 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 3462 return PackageManager.SIGNATURE_NO_MATCH; 3463 } 3464 3465 String msg = null; 3466 try { 3467 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 3468 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 3469 + scannedPkg.packageName); 3470 return PackageManager.SIGNATURE_MATCH; 3471 } 3472 } catch (CertificateException e) { 3473 msg = e.getMessage(); 3474 } 3475 3476 logCriticalInfo(Log.INFO, 3477 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 3478 return PackageManager.SIGNATURE_NO_MATCH; 3479 } 3480 3481 @Override 3482 public String[] getPackagesForUid(int uid) { 3483 uid = UserHandle.getAppId(uid); 3484 // reader 3485 synchronized (mPackages) { 3486 Object obj = mSettings.getUserIdLPr(uid); 3487 if (obj instanceof SharedUserSetting) { 3488 final SharedUserSetting sus = (SharedUserSetting) obj; 3489 final int N = sus.packages.size(); 3490 final String[] res = new String[N]; 3491 final Iterator<PackageSetting> it = sus.packages.iterator(); 3492 int i = 0; 3493 while (it.hasNext()) { 3494 res[i++] = it.next().name; 3495 } 3496 return res; 3497 } else if (obj instanceof PackageSetting) { 3498 final PackageSetting ps = (PackageSetting) obj; 3499 return new String[] { ps.name }; 3500 } 3501 } 3502 return null; 3503 } 3504 3505 @Override 3506 public String getNameForUid(int uid) { 3507 // reader 3508 synchronized (mPackages) { 3509 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3510 if (obj instanceof SharedUserSetting) { 3511 final SharedUserSetting sus = (SharedUserSetting) obj; 3512 return sus.name + ":" + sus.userId; 3513 } else if (obj instanceof PackageSetting) { 3514 final PackageSetting ps = (PackageSetting) obj; 3515 return ps.name; 3516 } 3517 } 3518 return null; 3519 } 3520 3521 @Override 3522 public int getUidForSharedUser(String sharedUserName) { 3523 if(sharedUserName == null) { 3524 return -1; 3525 } 3526 // reader 3527 synchronized (mPackages) { 3528 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 3529 if (suid == null) { 3530 return -1; 3531 } 3532 return suid.userId; 3533 } 3534 } 3535 3536 @Override 3537 public int getFlagsForUid(int uid) { 3538 synchronized (mPackages) { 3539 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3540 if (obj instanceof SharedUserSetting) { 3541 final SharedUserSetting sus = (SharedUserSetting) obj; 3542 return sus.pkgFlags; 3543 } else if (obj instanceof PackageSetting) { 3544 final PackageSetting ps = (PackageSetting) obj; 3545 return ps.pkgFlags; 3546 } 3547 } 3548 return 0; 3549 } 3550 3551 @Override 3552 public int getPrivateFlagsForUid(int uid) { 3553 synchronized (mPackages) { 3554 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3555 if (obj instanceof SharedUserSetting) { 3556 final SharedUserSetting sus = (SharedUserSetting) obj; 3557 return sus.pkgPrivateFlags; 3558 } else if (obj instanceof PackageSetting) { 3559 final PackageSetting ps = (PackageSetting) obj; 3560 return ps.pkgPrivateFlags; 3561 } 3562 } 3563 return 0; 3564 } 3565 3566 @Override 3567 public boolean isUidPrivileged(int uid) { 3568 uid = UserHandle.getAppId(uid); 3569 // reader 3570 synchronized (mPackages) { 3571 Object obj = mSettings.getUserIdLPr(uid); 3572 if (obj instanceof SharedUserSetting) { 3573 final SharedUserSetting sus = (SharedUserSetting) obj; 3574 final Iterator<PackageSetting> it = sus.packages.iterator(); 3575 while (it.hasNext()) { 3576 if (it.next().isPrivileged()) { 3577 return true; 3578 } 3579 } 3580 } else if (obj instanceof PackageSetting) { 3581 final PackageSetting ps = (PackageSetting) obj; 3582 return ps.isPrivileged(); 3583 } 3584 } 3585 return false; 3586 } 3587 3588 @Override 3589 public String[] getAppOpPermissionPackages(String permissionName) { 3590 synchronized (mPackages) { 3591 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 3592 if (pkgs == null) { 3593 return null; 3594 } 3595 return pkgs.toArray(new String[pkgs.size()]); 3596 } 3597 } 3598 3599 @Override 3600 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 3601 int flags, int userId) { 3602 if (!sUserManager.exists(userId)) return null; 3603 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 3604 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3605 return chooseBestActivity(intent, resolvedType, flags, query, userId); 3606 } 3607 3608 @Override 3609 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 3610 IntentFilter filter, int match, ComponentName activity) { 3611 final int userId = UserHandle.getCallingUserId(); 3612 if (DEBUG_PREFERRED) { 3613 Log.v(TAG, "setLastChosenActivity intent=" + intent 3614 + " resolvedType=" + resolvedType 3615 + " flags=" + flags 3616 + " filter=" + filter 3617 + " match=" + match 3618 + " activity=" + activity); 3619 filter.dump(new PrintStreamPrinter(System.out), " "); 3620 } 3621 intent.setComponent(null); 3622 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3623 // Find any earlier preferred or last chosen entries and nuke them 3624 findPreferredActivity(intent, resolvedType, 3625 flags, query, 0, false, true, false, userId); 3626 // Add the new activity as the last chosen for this filter 3627 addPreferredActivityInternal(filter, match, null, activity, false, userId, 3628 "Setting last chosen"); 3629 } 3630 3631 @Override 3632 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 3633 final int userId = UserHandle.getCallingUserId(); 3634 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 3635 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3636 return findPreferredActivity(intent, resolvedType, flags, query, 0, 3637 false, false, false, userId); 3638 } 3639 3640 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 3641 int flags, List<ResolveInfo> query, int userId) { 3642 if (query != null) { 3643 final int N = query.size(); 3644 if (N == 1) { 3645 return query.get(0); 3646 } else if (N > 1) { 3647 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3648 // If there is more than one activity with the same priority, 3649 // then let the user decide between them. 3650 ResolveInfo r0 = query.get(0); 3651 ResolveInfo r1 = query.get(1); 3652 if (DEBUG_INTENT_MATCHING || debug) { 3653 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 3654 + r1.activityInfo.name + "=" + r1.priority); 3655 } 3656 // If the first activity has a higher priority, or a different 3657 // default, then it is always desireable to pick it. 3658 if (r0.priority != r1.priority 3659 || r0.preferredOrder != r1.preferredOrder 3660 || r0.isDefault != r1.isDefault) { 3661 return query.get(0); 3662 } 3663 // If we have saved a preference for a preferred activity for 3664 // this Intent, use that. 3665 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 3666 flags, query, r0.priority, true, false, debug, userId); 3667 if (ri != null) { 3668 return ri; 3669 } 3670 if (userId != 0) { 3671 ri = new ResolveInfo(mResolveInfo); 3672 ri.activityInfo = new ActivityInfo(ri.activityInfo); 3673 ri.activityInfo.applicationInfo = new ApplicationInfo( 3674 ri.activityInfo.applicationInfo); 3675 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 3676 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 3677 return ri; 3678 } 3679 return mResolveInfo; 3680 } 3681 } 3682 return null; 3683 } 3684 3685 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 3686 int flags, List<ResolveInfo> query, boolean debug, int userId) { 3687 final int N = query.size(); 3688 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 3689 .get(userId); 3690 // Get the list of persistent preferred activities that handle the intent 3691 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 3692 List<PersistentPreferredActivity> pprefs = ppir != null 3693 ? ppir.queryIntent(intent, resolvedType, 3694 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3695 : null; 3696 if (pprefs != null && pprefs.size() > 0) { 3697 final int M = pprefs.size(); 3698 for (int i=0; i<M; i++) { 3699 final PersistentPreferredActivity ppa = pprefs.get(i); 3700 if (DEBUG_PREFERRED || debug) { 3701 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 3702 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 3703 + "\n component=" + ppa.mComponent); 3704 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3705 } 3706 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 3707 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3708 if (DEBUG_PREFERRED || debug) { 3709 Slog.v(TAG, "Found persistent preferred activity:"); 3710 if (ai != null) { 3711 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3712 } else { 3713 Slog.v(TAG, " null"); 3714 } 3715 } 3716 if (ai == null) { 3717 // This previously registered persistent preferred activity 3718 // component is no longer known. Ignore it and do NOT remove it. 3719 continue; 3720 } 3721 for (int j=0; j<N; j++) { 3722 final ResolveInfo ri = query.get(j); 3723 if (!ri.activityInfo.applicationInfo.packageName 3724 .equals(ai.applicationInfo.packageName)) { 3725 continue; 3726 } 3727 if (!ri.activityInfo.name.equals(ai.name)) { 3728 continue; 3729 } 3730 // Found a persistent preference that can handle the intent. 3731 if (DEBUG_PREFERRED || debug) { 3732 Slog.v(TAG, "Returning persistent preferred activity: " + 3733 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3734 } 3735 return ri; 3736 } 3737 } 3738 } 3739 return null; 3740 } 3741 3742 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 3743 List<ResolveInfo> query, int priority, boolean always, 3744 boolean removeMatches, boolean debug, int userId) { 3745 if (!sUserManager.exists(userId)) return null; 3746 // writer 3747 synchronized (mPackages) { 3748 if (intent.getSelector() != null) { 3749 intent = intent.getSelector(); 3750 } 3751 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3752 3753 // Try to find a matching persistent preferred activity. 3754 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 3755 debug, userId); 3756 3757 // If a persistent preferred activity matched, use it. 3758 if (pri != null) { 3759 return pri; 3760 } 3761 3762 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 3763 // Get the list of preferred activities that handle the intent 3764 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 3765 List<PreferredActivity> prefs = pir != null 3766 ? pir.queryIntent(intent, resolvedType, 3767 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3768 : null; 3769 if (prefs != null && prefs.size() > 0) { 3770 boolean changed = false; 3771 try { 3772 // First figure out how good the original match set is. 3773 // We will only allow preferred activities that came 3774 // from the same match quality. 3775 int match = 0; 3776 3777 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 3778 3779 final int N = query.size(); 3780 for (int j=0; j<N; j++) { 3781 final ResolveInfo ri = query.get(j); 3782 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 3783 + ": 0x" + Integer.toHexString(match)); 3784 if (ri.match > match) { 3785 match = ri.match; 3786 } 3787 } 3788 3789 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 3790 + Integer.toHexString(match)); 3791 3792 match &= IntentFilter.MATCH_CATEGORY_MASK; 3793 final int M = prefs.size(); 3794 for (int i=0; i<M; i++) { 3795 final PreferredActivity pa = prefs.get(i); 3796 if (DEBUG_PREFERRED || debug) { 3797 Slog.v(TAG, "Checking PreferredActivity ds=" 3798 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 3799 + "\n component=" + pa.mPref.mComponent); 3800 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3801 } 3802 if (pa.mPref.mMatch != match) { 3803 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 3804 + Integer.toHexString(pa.mPref.mMatch)); 3805 continue; 3806 } 3807 // If it's not an "always" type preferred activity and that's what we're 3808 // looking for, skip it. 3809 if (always && !pa.mPref.mAlways) { 3810 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 3811 continue; 3812 } 3813 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 3814 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3815 if (DEBUG_PREFERRED || debug) { 3816 Slog.v(TAG, "Found preferred activity:"); 3817 if (ai != null) { 3818 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3819 } else { 3820 Slog.v(TAG, " null"); 3821 } 3822 } 3823 if (ai == null) { 3824 // This previously registered preferred activity 3825 // component is no longer known. Most likely an update 3826 // to the app was installed and in the new version this 3827 // component no longer exists. Clean it up by removing 3828 // it from the preferred activities list, and skip it. 3829 Slog.w(TAG, "Removing dangling preferred activity: " 3830 + pa.mPref.mComponent); 3831 pir.removeFilter(pa); 3832 changed = true; 3833 continue; 3834 } 3835 for (int j=0; j<N; j++) { 3836 final ResolveInfo ri = query.get(j); 3837 if (!ri.activityInfo.applicationInfo.packageName 3838 .equals(ai.applicationInfo.packageName)) { 3839 continue; 3840 } 3841 if (!ri.activityInfo.name.equals(ai.name)) { 3842 continue; 3843 } 3844 3845 if (removeMatches) { 3846 pir.removeFilter(pa); 3847 changed = true; 3848 if (DEBUG_PREFERRED) { 3849 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 3850 } 3851 break; 3852 } 3853 3854 // Okay we found a previously set preferred or last chosen app. 3855 // If the result set is different from when this 3856 // was created, we need to clear it and re-ask the 3857 // user their preference, if we're looking for an "always" type entry. 3858 if (always && !pa.mPref.sameSet(query)) { 3859 Slog.i(TAG, "Result set changed, dropping preferred activity for " 3860 + intent + " type " + resolvedType); 3861 if (DEBUG_PREFERRED) { 3862 Slog.v(TAG, "Removing preferred activity since set changed " 3863 + pa.mPref.mComponent); 3864 } 3865 pir.removeFilter(pa); 3866 // Re-add the filter as a "last chosen" entry (!always) 3867 PreferredActivity lastChosen = new PreferredActivity( 3868 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 3869 pir.addFilter(lastChosen); 3870 changed = true; 3871 return null; 3872 } 3873 3874 // Yay! Either the set matched or we're looking for the last chosen 3875 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 3876 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3877 return ri; 3878 } 3879 } 3880 } finally { 3881 if (changed) { 3882 if (DEBUG_PREFERRED) { 3883 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 3884 } 3885 scheduleWritePackageRestrictionsLocked(userId); 3886 } 3887 } 3888 } 3889 } 3890 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 3891 return null; 3892 } 3893 3894 /* 3895 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 3896 */ 3897 @Override 3898 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 3899 int targetUserId) { 3900 mContext.enforceCallingOrSelfPermission( 3901 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 3902 List<CrossProfileIntentFilter> matches = 3903 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 3904 if (matches != null) { 3905 int size = matches.size(); 3906 for (int i = 0; i < size; i++) { 3907 if (matches.get(i).getTargetUserId() == targetUserId) return true; 3908 } 3909 } 3910 return false; 3911 } 3912 3913 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 3914 String resolvedType, int userId) { 3915 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 3916 if (resolver != null) { 3917 return resolver.queryIntent(intent, resolvedType, false, userId); 3918 } 3919 return null; 3920 } 3921 3922 @Override 3923 public List<ResolveInfo> queryIntentActivities(Intent intent, 3924 String resolvedType, int flags, int userId) { 3925 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3926 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 3927 ComponentName comp = intent.getComponent(); 3928 if (comp == null) { 3929 if (intent.getSelector() != null) { 3930 intent = intent.getSelector(); 3931 comp = intent.getComponent(); 3932 } 3933 } 3934 3935 if (comp != null) { 3936 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3937 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 3938 if (ai != null) { 3939 final ResolveInfo ri = new ResolveInfo(); 3940 ri.activityInfo = ai; 3941 list.add(ri); 3942 } 3943 return list; 3944 } 3945 3946 // reader 3947 synchronized (mPackages) { 3948 final String pkgName = intent.getPackage(); 3949 if (pkgName == null) { 3950 List<CrossProfileIntentFilter> matchingFilters = 3951 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 3952 // Check for results that need to skip the current profile. 3953 ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 3954 resolvedType, flags, userId); 3955 if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { 3956 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 3957 result.add(resolveInfo); 3958 return filterIfNotPrimaryUser(result, userId); 3959 } 3960 3961 // Check for results in the current profile. 3962 List<ResolveInfo> result = mActivities.queryIntent( 3963 intent, resolvedType, flags, userId); 3964 3965 // Check for cross profile results. 3966 resolveInfo = queryCrossProfileIntents( 3967 matchingFilters, intent, resolvedType, flags, userId); 3968 if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { 3969 result.add(resolveInfo); 3970 Collections.sort(result, mResolvePrioritySorter); 3971 } 3972 result = filterIfNotPrimaryUser(result, userId); 3973 if (result.size() > 1 && hasWebURI(intent)) { 3974 return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result); 3975 } 3976 return result; 3977 } 3978 final PackageParser.Package pkg = mPackages.get(pkgName); 3979 if (pkg != null) { 3980 return filterIfNotPrimaryUser( 3981 mActivities.queryIntentForPackage( 3982 intent, resolvedType, flags, pkg.activities, userId), 3983 userId); 3984 } 3985 return new ArrayList<ResolveInfo>(); 3986 } 3987 } 3988 3989 private boolean isUserEnabled(int userId) { 3990 long callingId = Binder.clearCallingIdentity(); 3991 try { 3992 UserInfo userInfo = sUserManager.getUserInfo(userId); 3993 return userInfo != null && userInfo.isEnabled(); 3994 } finally { 3995 Binder.restoreCallingIdentity(callingId); 3996 } 3997 } 3998 3999 /** 4000 * Filter out activities with primaryUserOnly flag set, when current user is not the owner. 4001 * 4002 * @return filtered list 4003 */ 4004 private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) { 4005 if (userId == UserHandle.USER_OWNER) { 4006 return resolveInfos; 4007 } 4008 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 4009 ResolveInfo info = resolveInfos.get(i); 4010 if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 4011 resolveInfos.remove(i); 4012 } 4013 } 4014 return resolveInfos; 4015 } 4016 4017 private static boolean hasWebURI(Intent intent) { 4018 if (intent.getData() == null) { 4019 return false; 4020 } 4021 final String scheme = intent.getScheme(); 4022 if (TextUtils.isEmpty(scheme)) { 4023 return false; 4024 } 4025 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 4026 } 4027 4028 private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr( 4029 int flags, List<ResolveInfo> candidates) { 4030 if (DEBUG_PREFERRED) { 4031 Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " + 4032 candidates.size()); 4033 } 4034 4035 final int userId = UserHandle.getCallingUserId(); 4036 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 4037 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 4038 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 4039 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 4040 4041 synchronized (mPackages) { 4042 final int count = candidates.size(); 4043 // First, try to use the domain prefered App 4044 for (int n=0; n<count; n++) { 4045 ResolveInfo info = candidates.get(n); 4046 String packageName = info.activityInfo.packageName; 4047 PackageSetting ps = mSettings.mPackages.get(packageName); 4048 if (ps != null) { 4049 // Add to the special match all list (Browser use case) 4050 if (info.handleAllWebDataURI) { 4051 matchAllList.add(info); 4052 continue; 4053 } 4054 // Try to get the status from User settings first 4055 int status = getDomainVerificationStatusLPr(ps, userId); 4056 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 4057 result.add(info); 4058 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4059 neverList.add(info); 4060 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4061 undefinedList.add(info); 4062 } 4063 } 4064 } 4065 // If there is nothing selected, add all candidates and remove the ones that the User 4066 // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and 4067 // also remove any Browser Apps ones. 4068 // If there is still none after this pass, add all undefined one and Browser Apps and 4069 // let the User decide with the Disambiguation dialog if there are several ones. 4070 if (result.size() == 0) { 4071 result.addAll(candidates); 4072 } 4073 result.removeAll(neverList); 4074 result.removeAll(matchAllList); 4075 if (result.size() == 0) { 4076 result.addAll(undefinedList); 4077 if ((flags & MATCH_ALL) != 0) { 4078 result.addAll(matchAllList); 4079 } else { 4080 // Try to add the Default Browser if we can 4081 final String defaultBrowserPackageName = getDefaultBrowserPackageName( 4082 UserHandle.myUserId()); 4083 if (!TextUtils.isEmpty(defaultBrowserPackageName)) { 4084 boolean defaultBrowserFound = false; 4085 final int browserCount = matchAllList.size(); 4086 for (int n=0; n<browserCount; n++) { 4087 ResolveInfo browser = matchAllList.get(n); 4088 if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) { 4089 result.add(browser); 4090 defaultBrowserFound = true; 4091 break; 4092 } 4093 } 4094 if (!defaultBrowserFound) { 4095 result.addAll(matchAllList); 4096 } 4097 } else { 4098 result.addAll(matchAllList); 4099 } 4100 } 4101 } 4102 } 4103 if (DEBUG_PREFERRED) { 4104 Slog.v("TAG", "Filtered results with prefered activities. New candidates count: " + 4105 result.size()); 4106 } 4107 return result; 4108 } 4109 4110 private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 4111 int status = ps.getDomainVerificationStatusForUser(userId); 4112 // if none available, get the master status 4113 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4114 if (ps.getIntentFilterVerificationInfo() != null) { 4115 status = ps.getIntentFilterVerificationInfo().getStatus(); 4116 } 4117 } 4118 return status; 4119 } 4120 4121 private ResolveInfo querySkipCurrentProfileIntents( 4122 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4123 int flags, int sourceUserId) { 4124 if (matchingFilters != null) { 4125 int size = matchingFilters.size(); 4126 for (int i = 0; i < size; i ++) { 4127 CrossProfileIntentFilter filter = matchingFilters.get(i); 4128 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 4129 // Checking if there are activities in the target user that can handle the 4130 // intent. 4131 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4132 flags, sourceUserId); 4133 if (resolveInfo != null) { 4134 return resolveInfo; 4135 } 4136 } 4137 } 4138 } 4139 return null; 4140 } 4141 4142 // Return matching ResolveInfo if any for skip current profile intent filters. 4143 private ResolveInfo queryCrossProfileIntents( 4144 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4145 int flags, int sourceUserId) { 4146 if (matchingFilters != null) { 4147 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 4148 // match the same intent. For performance reasons, it is better not to 4149 // run queryIntent twice for the same userId 4150 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 4151 int size = matchingFilters.size(); 4152 for (int i = 0; i < size; i++) { 4153 CrossProfileIntentFilter filter = matchingFilters.get(i); 4154 int targetUserId = filter.getTargetUserId(); 4155 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 4156 && !alreadyTriedUserIds.get(targetUserId)) { 4157 // Checking if there are activities in the target user that can handle the 4158 // intent. 4159 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4160 flags, sourceUserId); 4161 if (resolveInfo != null) return resolveInfo; 4162 alreadyTriedUserIds.put(targetUserId, true); 4163 } 4164 } 4165 } 4166 return null; 4167 } 4168 4169 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 4170 String resolvedType, int flags, int sourceUserId) { 4171 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4172 resolvedType, flags, filter.getTargetUserId()); 4173 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 4174 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 4175 } 4176 return null; 4177 } 4178 4179 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 4180 int sourceUserId, int targetUserId) { 4181 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 4182 String className; 4183 if (targetUserId == UserHandle.USER_OWNER) { 4184 className = FORWARD_INTENT_TO_USER_OWNER; 4185 } else { 4186 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 4187 } 4188 ComponentName forwardingActivityComponentName = new ComponentName( 4189 mAndroidApplication.packageName, className); 4190 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 4191 sourceUserId); 4192 if (targetUserId == UserHandle.USER_OWNER) { 4193 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 4194 forwardingResolveInfo.noResourceId = true; 4195 } 4196 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 4197 forwardingResolveInfo.priority = 0; 4198 forwardingResolveInfo.preferredOrder = 0; 4199 forwardingResolveInfo.match = 0; 4200 forwardingResolveInfo.isDefault = true; 4201 forwardingResolveInfo.filter = filter; 4202 forwardingResolveInfo.targetUserId = targetUserId; 4203 return forwardingResolveInfo; 4204 } 4205 4206 @Override 4207 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 4208 Intent[] specifics, String[] specificTypes, Intent intent, 4209 String resolvedType, int flags, int userId) { 4210 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4211 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 4212 false, "query intent activity options"); 4213 final String resultsAction = intent.getAction(); 4214 4215 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 4216 | PackageManager.GET_RESOLVED_FILTER, userId); 4217 4218 if (DEBUG_INTENT_MATCHING) { 4219 Log.v(TAG, "Query " + intent + ": " + results); 4220 } 4221 4222 int specificsPos = 0; 4223 int N; 4224 4225 // todo: note that the algorithm used here is O(N^2). This 4226 // isn't a problem in our current environment, but if we start running 4227 // into situations where we have more than 5 or 10 matches then this 4228 // should probably be changed to something smarter... 4229 4230 // First we go through and resolve each of the specific items 4231 // that were supplied, taking care of removing any corresponding 4232 // duplicate items in the generic resolve list. 4233 if (specifics != null) { 4234 for (int i=0; i<specifics.length; i++) { 4235 final Intent sintent = specifics[i]; 4236 if (sintent == null) { 4237 continue; 4238 } 4239 4240 if (DEBUG_INTENT_MATCHING) { 4241 Log.v(TAG, "Specific #" + i + ": " + sintent); 4242 } 4243 4244 String action = sintent.getAction(); 4245 if (resultsAction != null && resultsAction.equals(action)) { 4246 // If this action was explicitly requested, then don't 4247 // remove things that have it. 4248 action = null; 4249 } 4250 4251 ResolveInfo ri = null; 4252 ActivityInfo ai = null; 4253 4254 ComponentName comp = sintent.getComponent(); 4255 if (comp == null) { 4256 ri = resolveIntent( 4257 sintent, 4258 specificTypes != null ? specificTypes[i] : null, 4259 flags, userId); 4260 if (ri == null) { 4261 continue; 4262 } 4263 if (ri == mResolveInfo) { 4264 // ACK! Must do something better with this. 4265 } 4266 ai = ri.activityInfo; 4267 comp = new ComponentName(ai.applicationInfo.packageName, 4268 ai.name); 4269 } else { 4270 ai = getActivityInfo(comp, flags, userId); 4271 if (ai == null) { 4272 continue; 4273 } 4274 } 4275 4276 // Look for any generic query activities that are duplicates 4277 // of this specific one, and remove them from the results. 4278 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 4279 N = results.size(); 4280 int j; 4281 for (j=specificsPos; j<N; j++) { 4282 ResolveInfo sri = results.get(j); 4283 if ((sri.activityInfo.name.equals(comp.getClassName()) 4284 && sri.activityInfo.applicationInfo.packageName.equals( 4285 comp.getPackageName())) 4286 || (action != null && sri.filter.matchAction(action))) { 4287 results.remove(j); 4288 if (DEBUG_INTENT_MATCHING) Log.v( 4289 TAG, "Removing duplicate item from " + j 4290 + " due to specific " + specificsPos); 4291 if (ri == null) { 4292 ri = sri; 4293 } 4294 j--; 4295 N--; 4296 } 4297 } 4298 4299 // Add this specific item to its proper place. 4300 if (ri == null) { 4301 ri = new ResolveInfo(); 4302 ri.activityInfo = ai; 4303 } 4304 results.add(specificsPos, ri); 4305 ri.specificIndex = i; 4306 specificsPos++; 4307 } 4308 } 4309 4310 // Now we go through the remaining generic results and remove any 4311 // duplicate actions that are found here. 4312 N = results.size(); 4313 for (int i=specificsPos; i<N-1; i++) { 4314 final ResolveInfo rii = results.get(i); 4315 if (rii.filter == null) { 4316 continue; 4317 } 4318 4319 // Iterate over all of the actions of this result's intent 4320 // filter... typically this should be just one. 4321 final Iterator<String> it = rii.filter.actionsIterator(); 4322 if (it == null) { 4323 continue; 4324 } 4325 while (it.hasNext()) { 4326 final String action = it.next(); 4327 if (resultsAction != null && resultsAction.equals(action)) { 4328 // If this action was explicitly requested, then don't 4329 // remove things that have it. 4330 continue; 4331 } 4332 for (int j=i+1; j<N; j++) { 4333 final ResolveInfo rij = results.get(j); 4334 if (rij.filter != null && rij.filter.hasAction(action)) { 4335 results.remove(j); 4336 if (DEBUG_INTENT_MATCHING) Log.v( 4337 TAG, "Removing duplicate item from " + j 4338 + " due to action " + action + " at " + i); 4339 j--; 4340 N--; 4341 } 4342 } 4343 } 4344 4345 // If the caller didn't request filter information, drop it now 4346 // so we don't have to marshall/unmarshall it. 4347 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4348 rii.filter = null; 4349 } 4350 } 4351 4352 // Filter out the caller activity if so requested. 4353 if (caller != null) { 4354 N = results.size(); 4355 for (int i=0; i<N; i++) { 4356 ActivityInfo ainfo = results.get(i).activityInfo; 4357 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 4358 && caller.getClassName().equals(ainfo.name)) { 4359 results.remove(i); 4360 break; 4361 } 4362 } 4363 } 4364 4365 // If the caller didn't request filter information, 4366 // drop them now so we don't have to 4367 // marshall/unmarshall it. 4368 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4369 N = results.size(); 4370 for (int i=0; i<N; i++) { 4371 results.get(i).filter = null; 4372 } 4373 } 4374 4375 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 4376 return results; 4377 } 4378 4379 @Override 4380 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 4381 int userId) { 4382 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4383 ComponentName comp = intent.getComponent(); 4384 if (comp == null) { 4385 if (intent.getSelector() != null) { 4386 intent = intent.getSelector(); 4387 comp = intent.getComponent(); 4388 } 4389 } 4390 if (comp != null) { 4391 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4392 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 4393 if (ai != null) { 4394 ResolveInfo ri = new ResolveInfo(); 4395 ri.activityInfo = ai; 4396 list.add(ri); 4397 } 4398 return list; 4399 } 4400 4401 // reader 4402 synchronized (mPackages) { 4403 String pkgName = intent.getPackage(); 4404 if (pkgName == null) { 4405 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 4406 } 4407 final PackageParser.Package pkg = mPackages.get(pkgName); 4408 if (pkg != null) { 4409 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 4410 userId); 4411 } 4412 return null; 4413 } 4414 } 4415 4416 @Override 4417 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 4418 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 4419 if (!sUserManager.exists(userId)) return null; 4420 if (query != null) { 4421 if (query.size() >= 1) { 4422 // If there is more than one service with the same priority, 4423 // just arbitrarily pick the first one. 4424 return query.get(0); 4425 } 4426 } 4427 return null; 4428 } 4429 4430 @Override 4431 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 4432 int userId) { 4433 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4434 ComponentName comp = intent.getComponent(); 4435 if (comp == null) { 4436 if (intent.getSelector() != null) { 4437 intent = intent.getSelector(); 4438 comp = intent.getComponent(); 4439 } 4440 } 4441 if (comp != null) { 4442 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4443 final ServiceInfo si = getServiceInfo(comp, flags, userId); 4444 if (si != null) { 4445 final ResolveInfo ri = new ResolveInfo(); 4446 ri.serviceInfo = si; 4447 list.add(ri); 4448 } 4449 return list; 4450 } 4451 4452 // reader 4453 synchronized (mPackages) { 4454 String pkgName = intent.getPackage(); 4455 if (pkgName == null) { 4456 return mServices.queryIntent(intent, resolvedType, flags, userId); 4457 } 4458 final PackageParser.Package pkg = mPackages.get(pkgName); 4459 if (pkg != null) { 4460 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 4461 userId); 4462 } 4463 return null; 4464 } 4465 } 4466 4467 @Override 4468 public List<ResolveInfo> queryIntentContentProviders( 4469 Intent intent, String resolvedType, int flags, int userId) { 4470 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4471 ComponentName comp = intent.getComponent(); 4472 if (comp == null) { 4473 if (intent.getSelector() != null) { 4474 intent = intent.getSelector(); 4475 comp = intent.getComponent(); 4476 } 4477 } 4478 if (comp != null) { 4479 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4480 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 4481 if (pi != null) { 4482 final ResolveInfo ri = new ResolveInfo(); 4483 ri.providerInfo = pi; 4484 list.add(ri); 4485 } 4486 return list; 4487 } 4488 4489 // reader 4490 synchronized (mPackages) { 4491 String pkgName = intent.getPackage(); 4492 if (pkgName == null) { 4493 return mProviders.queryIntent(intent, resolvedType, flags, userId); 4494 } 4495 final PackageParser.Package pkg = mPackages.get(pkgName); 4496 if (pkg != null) { 4497 return mProviders.queryIntentForPackage( 4498 intent, resolvedType, flags, pkg.providers, userId); 4499 } 4500 return null; 4501 } 4502 } 4503 4504 @Override 4505 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 4506 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4507 4508 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 4509 4510 // writer 4511 synchronized (mPackages) { 4512 ArrayList<PackageInfo> list; 4513 if (listUninstalled) { 4514 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 4515 for (PackageSetting ps : mSettings.mPackages.values()) { 4516 PackageInfo pi; 4517 if (ps.pkg != null) { 4518 pi = generatePackageInfo(ps.pkg, flags, userId); 4519 } else { 4520 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4521 } 4522 if (pi != null) { 4523 list.add(pi); 4524 } 4525 } 4526 } else { 4527 list = new ArrayList<PackageInfo>(mPackages.size()); 4528 for (PackageParser.Package p : mPackages.values()) { 4529 PackageInfo pi = generatePackageInfo(p, flags, userId); 4530 if (pi != null) { 4531 list.add(pi); 4532 } 4533 } 4534 } 4535 4536 return new ParceledListSlice<PackageInfo>(list); 4537 } 4538 } 4539 4540 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 4541 String[] permissions, boolean[] tmp, int flags, int userId) { 4542 int numMatch = 0; 4543 final PermissionsState permissionsState = ps.getPermissionsState(); 4544 for (int i=0; i<permissions.length; i++) { 4545 final String permission = permissions[i]; 4546 if (permissionsState.hasPermission(permission, userId)) { 4547 tmp[i] = true; 4548 numMatch++; 4549 } else { 4550 tmp[i] = false; 4551 } 4552 } 4553 if (numMatch == 0) { 4554 return; 4555 } 4556 PackageInfo pi; 4557 if (ps.pkg != null) { 4558 pi = generatePackageInfo(ps.pkg, flags, userId); 4559 } else { 4560 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4561 } 4562 // The above might return null in cases of uninstalled apps or install-state 4563 // skew across users/profiles. 4564 if (pi != null) { 4565 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 4566 if (numMatch == permissions.length) { 4567 pi.requestedPermissions = permissions; 4568 } else { 4569 pi.requestedPermissions = new String[numMatch]; 4570 numMatch = 0; 4571 for (int i=0; i<permissions.length; i++) { 4572 if (tmp[i]) { 4573 pi.requestedPermissions[numMatch] = permissions[i]; 4574 numMatch++; 4575 } 4576 } 4577 } 4578 } 4579 list.add(pi); 4580 } 4581 } 4582 4583 @Override 4584 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 4585 String[] permissions, int flags, int userId) { 4586 if (!sUserManager.exists(userId)) return null; 4587 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4588 4589 // writer 4590 synchronized (mPackages) { 4591 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 4592 boolean[] tmpBools = new boolean[permissions.length]; 4593 if (listUninstalled) { 4594 for (PackageSetting ps : mSettings.mPackages.values()) { 4595 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 4596 } 4597 } else { 4598 for (PackageParser.Package pkg : mPackages.values()) { 4599 PackageSetting ps = (PackageSetting)pkg.mExtras; 4600 if (ps != null) { 4601 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 4602 userId); 4603 } 4604 } 4605 } 4606 4607 return new ParceledListSlice<PackageInfo>(list); 4608 } 4609 } 4610 4611 @Override 4612 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 4613 if (!sUserManager.exists(userId)) return null; 4614 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4615 4616 // writer 4617 synchronized (mPackages) { 4618 ArrayList<ApplicationInfo> list; 4619 if (listUninstalled) { 4620 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 4621 for (PackageSetting ps : mSettings.mPackages.values()) { 4622 ApplicationInfo ai; 4623 if (ps.pkg != null) { 4624 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 4625 ps.readUserState(userId), userId); 4626 } else { 4627 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 4628 } 4629 if (ai != null) { 4630 list.add(ai); 4631 } 4632 } 4633 } else { 4634 list = new ArrayList<ApplicationInfo>(mPackages.size()); 4635 for (PackageParser.Package p : mPackages.values()) { 4636 if (p.mExtras != null) { 4637 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4638 ((PackageSetting)p.mExtras).readUserState(userId), userId); 4639 if (ai != null) { 4640 list.add(ai); 4641 } 4642 } 4643 } 4644 } 4645 4646 return new ParceledListSlice<ApplicationInfo>(list); 4647 } 4648 } 4649 4650 public List<ApplicationInfo> getPersistentApplications(int flags) { 4651 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 4652 4653 // reader 4654 synchronized (mPackages) { 4655 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 4656 final int userId = UserHandle.getCallingUserId(); 4657 while (i.hasNext()) { 4658 final PackageParser.Package p = i.next(); 4659 if (p.applicationInfo != null 4660 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 4661 && (!mSafeMode || isSystemApp(p))) { 4662 PackageSetting ps = mSettings.mPackages.get(p.packageName); 4663 if (ps != null) { 4664 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4665 ps.readUserState(userId), userId); 4666 if (ai != null) { 4667 finalList.add(ai); 4668 } 4669 } 4670 } 4671 } 4672 } 4673 4674 return finalList; 4675 } 4676 4677 @Override 4678 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 4679 if (!sUserManager.exists(userId)) return null; 4680 // reader 4681 synchronized (mPackages) { 4682 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 4683 PackageSetting ps = provider != null 4684 ? mSettings.mPackages.get(provider.owner.packageName) 4685 : null; 4686 return ps != null 4687 && mSettings.isEnabledLPr(provider.info, flags, userId) 4688 && (!mSafeMode || (provider.info.applicationInfo.flags 4689 &ApplicationInfo.FLAG_SYSTEM) != 0) 4690 ? PackageParser.generateProviderInfo(provider, flags, 4691 ps.readUserState(userId), userId) 4692 : null; 4693 } 4694 } 4695 4696 /** 4697 * @deprecated 4698 */ 4699 @Deprecated 4700 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 4701 // reader 4702 synchronized (mPackages) { 4703 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 4704 .entrySet().iterator(); 4705 final int userId = UserHandle.getCallingUserId(); 4706 while (i.hasNext()) { 4707 Map.Entry<String, PackageParser.Provider> entry = i.next(); 4708 PackageParser.Provider p = entry.getValue(); 4709 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4710 4711 if (ps != null && p.syncable 4712 && (!mSafeMode || (p.info.applicationInfo.flags 4713 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 4714 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 4715 ps.readUserState(userId), userId); 4716 if (info != null) { 4717 outNames.add(entry.getKey()); 4718 outInfo.add(info); 4719 } 4720 } 4721 } 4722 } 4723 } 4724 4725 @Override 4726 public List<ProviderInfo> queryContentProviders(String processName, 4727 int uid, int flags) { 4728 ArrayList<ProviderInfo> finalList = null; 4729 // reader 4730 synchronized (mPackages) { 4731 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 4732 final int userId = processName != null ? 4733 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 4734 while (i.hasNext()) { 4735 final PackageParser.Provider p = i.next(); 4736 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4737 if (ps != null && p.info.authority != null 4738 && (processName == null 4739 || (p.info.processName.equals(processName) 4740 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 4741 && mSettings.isEnabledLPr(p.info, flags, userId) 4742 && (!mSafeMode 4743 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 4744 if (finalList == null) { 4745 finalList = new ArrayList<ProviderInfo>(3); 4746 } 4747 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 4748 ps.readUserState(userId), userId); 4749 if (info != null) { 4750 finalList.add(info); 4751 } 4752 } 4753 } 4754 } 4755 4756 if (finalList != null) { 4757 Collections.sort(finalList, mProviderInitOrderSorter); 4758 } 4759 4760 return finalList; 4761 } 4762 4763 @Override 4764 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 4765 int flags) { 4766 // reader 4767 synchronized (mPackages) { 4768 final PackageParser.Instrumentation i = mInstrumentation.get(name); 4769 return PackageParser.generateInstrumentationInfo(i, flags); 4770 } 4771 } 4772 4773 @Override 4774 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 4775 int flags) { 4776 ArrayList<InstrumentationInfo> finalList = 4777 new ArrayList<InstrumentationInfo>(); 4778 4779 // reader 4780 synchronized (mPackages) { 4781 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 4782 while (i.hasNext()) { 4783 final PackageParser.Instrumentation p = i.next(); 4784 if (targetPackage == null 4785 || targetPackage.equals(p.info.targetPackage)) { 4786 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 4787 flags); 4788 if (ii != null) { 4789 finalList.add(ii); 4790 } 4791 } 4792 } 4793 } 4794 4795 return finalList; 4796 } 4797 4798 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 4799 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 4800 if (overlays == null) { 4801 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 4802 return; 4803 } 4804 for (PackageParser.Package opkg : overlays.values()) { 4805 // Not much to do if idmap fails: we already logged the error 4806 // and we certainly don't want to abort installation of pkg simply 4807 // because an overlay didn't fit properly. For these reasons, 4808 // ignore the return value of createIdmapForPackagePairLI. 4809 createIdmapForPackagePairLI(pkg, opkg); 4810 } 4811 } 4812 4813 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 4814 PackageParser.Package opkg) { 4815 if (!opkg.mTrustedOverlay) { 4816 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 4817 opkg.baseCodePath + ": overlay not trusted"); 4818 return false; 4819 } 4820 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 4821 if (overlaySet == null) { 4822 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 4823 opkg.baseCodePath + " but target package has no known overlays"); 4824 return false; 4825 } 4826 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4827 // TODO: generate idmap for split APKs 4828 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 4829 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 4830 + opkg.baseCodePath); 4831 return false; 4832 } 4833 PackageParser.Package[] overlayArray = 4834 overlaySet.values().toArray(new PackageParser.Package[0]); 4835 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 4836 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 4837 return p1.mOverlayPriority - p2.mOverlayPriority; 4838 } 4839 }; 4840 Arrays.sort(overlayArray, cmp); 4841 4842 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 4843 int i = 0; 4844 for (PackageParser.Package p : overlayArray) { 4845 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 4846 } 4847 return true; 4848 } 4849 4850 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 4851 final File[] files = dir.listFiles(); 4852 if (ArrayUtils.isEmpty(files)) { 4853 Log.d(TAG, "No files in app dir " + dir); 4854 return; 4855 } 4856 4857 if (DEBUG_PACKAGE_SCANNING) { 4858 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 4859 + " flags=0x" + Integer.toHexString(parseFlags)); 4860 } 4861 4862 for (File file : files) { 4863 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 4864 && !PackageInstallerService.isStageName(file.getName()); 4865 if (!isPackage) { 4866 // Ignore entries which are not packages 4867 continue; 4868 } 4869 try { 4870 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 4871 scanFlags, currentTime, null); 4872 } catch (PackageManagerException e) { 4873 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 4874 4875 // Delete invalid userdata apps 4876 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 4877 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 4878 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 4879 if (file.isDirectory()) { 4880 mInstaller.rmPackageDir(file.getAbsolutePath()); 4881 } else { 4882 file.delete(); 4883 } 4884 } 4885 } 4886 } 4887 } 4888 4889 private static File getSettingsProblemFile() { 4890 File dataDir = Environment.getDataDirectory(); 4891 File systemDir = new File(dataDir, "system"); 4892 File fname = new File(systemDir, "uiderrors.txt"); 4893 return fname; 4894 } 4895 4896 static void reportSettingsProblem(int priority, String msg) { 4897 logCriticalInfo(priority, msg); 4898 } 4899 4900 static void logCriticalInfo(int priority, String msg) { 4901 Slog.println(priority, TAG, msg); 4902 EventLogTags.writePmCriticalInfo(msg); 4903 try { 4904 File fname = getSettingsProblemFile(); 4905 FileOutputStream out = new FileOutputStream(fname, true); 4906 PrintWriter pw = new FastPrintWriter(out); 4907 SimpleDateFormat formatter = new SimpleDateFormat(); 4908 String dateString = formatter.format(new Date(System.currentTimeMillis())); 4909 pw.println(dateString + ": " + msg); 4910 pw.close(); 4911 FileUtils.setPermissions( 4912 fname.toString(), 4913 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 4914 -1, -1); 4915 } catch (java.io.IOException e) { 4916 } 4917 } 4918 4919 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 4920 PackageParser.Package pkg, File srcFile, int parseFlags) 4921 throws PackageManagerException { 4922 if (ps != null 4923 && ps.codePath.equals(srcFile) 4924 && ps.timeStamp == srcFile.lastModified() 4925 && !isCompatSignatureUpdateNeeded(pkg) 4926 && !isRecoverSignatureUpdateNeeded(pkg)) { 4927 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 4928 if (ps.signatures.mSignatures != null 4929 && ps.signatures.mSignatures.length != 0 4930 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) { 4931 // Optimization: reuse the existing cached certificates 4932 // if the package appears to be unchanged. 4933 pkg.mSignatures = ps.signatures.mSignatures; 4934 KeySetManagerService ksms = mSettings.mKeySetManagerService; 4935 synchronized (mPackages) { 4936 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 4937 } 4938 return; 4939 } 4940 4941 Slog.w(TAG, "PackageSetting for " + ps.name 4942 + " is missing signatures. Collecting certs again to recover them."); 4943 } else { 4944 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 4945 } 4946 4947 try { 4948 pp.collectCertificates(pkg, parseFlags); 4949 pp.collectManifestDigest(pkg); 4950 } catch (PackageParserException e) { 4951 throw PackageManagerException.from(e); 4952 } 4953 } 4954 4955 /* 4956 * Scan a package and return the newly parsed package. 4957 * Returns null in case of errors and the error code is stored in mLastScanError 4958 */ 4959 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 4960 long currentTime, UserHandle user) throws PackageManagerException { 4961 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 4962 parseFlags |= mDefParseFlags; 4963 PackageParser pp = new PackageParser(); 4964 pp.setSeparateProcesses(mSeparateProcesses); 4965 pp.setOnlyCoreApps(mOnlyCore); 4966 pp.setDisplayMetrics(mMetrics); 4967 4968 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 4969 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 4970 } 4971 4972 final PackageParser.Package pkg; 4973 try { 4974 pkg = pp.parsePackage(scanFile, parseFlags); 4975 } catch (PackageParserException e) { 4976 throw PackageManagerException.from(e); 4977 } 4978 4979 PackageSetting ps = null; 4980 PackageSetting updatedPkg; 4981 // reader 4982 synchronized (mPackages) { 4983 // Look to see if we already know about this package. 4984 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 4985 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 4986 // This package has been renamed to its original name. Let's 4987 // use that. 4988 ps = mSettings.peekPackageLPr(oldName); 4989 } 4990 // If there was no original package, see one for the real package name. 4991 if (ps == null) { 4992 ps = mSettings.peekPackageLPr(pkg.packageName); 4993 } 4994 // Check to see if this package could be hiding/updating a system 4995 // package. Must look for it either under the original or real 4996 // package name depending on our state. 4997 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 4998 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 4999 } 5000 boolean updatedPkgBetter = false; 5001 // First check if this is a system package that may involve an update 5002 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5003 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 5004 // it needs to drop FLAG_PRIVILEGED. 5005 if (locationIsPrivileged(scanFile)) { 5006 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5007 } else { 5008 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5009 } 5010 5011 if (ps != null && !ps.codePath.equals(scanFile)) { 5012 // The path has changed from what was last scanned... check the 5013 // version of the new path against what we have stored to determine 5014 // what to do. 5015 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 5016 if (pkg.mVersionCode <= ps.versionCode) { 5017 // The system package has been updated and the code path does not match 5018 // Ignore entry. Skip it. 5019 Slog.i(TAG, "Package " + ps.name + " at " + scanFile 5020 + " ignored: updated version " + ps.versionCode 5021 + " better than this " + pkg.mVersionCode); 5022 if (!updatedPkg.codePath.equals(scanFile)) { 5023 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 5024 + ps.name + " changing from " + updatedPkg.codePathString 5025 + " to " + scanFile); 5026 updatedPkg.codePath = scanFile; 5027 updatedPkg.codePathString = scanFile.toString(); 5028 updatedPkg.resourcePath = scanFile; 5029 updatedPkg.resourcePathString = scanFile.toString(); 5030 } 5031 updatedPkg.pkg = pkg; 5032 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null); 5033 } else { 5034 // The current app on the system partition is better than 5035 // what we have updated to on the data partition; switch 5036 // back to the system partition version. 5037 // At this point, its safely assumed that package installation for 5038 // apps in system partition will go through. If not there won't be a working 5039 // version of the app 5040 // writer 5041 synchronized (mPackages) { 5042 // Just remove the loaded entries from package lists. 5043 mPackages.remove(ps.name); 5044 } 5045 5046 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5047 + " reverting from " + ps.codePathString 5048 + ": new version " + pkg.mVersionCode 5049 + " better than installed " + ps.versionCode); 5050 5051 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5052 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 5053 getAppDexInstructionSets(ps)); 5054 synchronized (mInstallLock) { 5055 args.cleanUpResourcesLI(); 5056 } 5057 synchronized (mPackages) { 5058 mSettings.enableSystemPackageLPw(ps.name); 5059 } 5060 updatedPkgBetter = true; 5061 } 5062 } 5063 } 5064 5065 if (updatedPkg != null) { 5066 // An updated system app will not have the PARSE_IS_SYSTEM flag set 5067 // initially 5068 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 5069 5070 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 5071 // flag set initially 5072 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 5073 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 5074 } 5075 } 5076 5077 // Verify certificates against what was last scanned 5078 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 5079 5080 /* 5081 * A new system app appeared, but we already had a non-system one of the 5082 * same name installed earlier. 5083 */ 5084 boolean shouldHideSystemApp = false; 5085 if (updatedPkg == null && ps != null 5086 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 5087 /* 5088 * Check to make sure the signatures match first. If they don't, 5089 * wipe the installed application and its data. 5090 */ 5091 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 5092 != PackageManager.SIGNATURE_MATCH) { 5093 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 5094 + " signatures don't match existing userdata copy; removing"); 5095 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 5096 ps = null; 5097 } else { 5098 /* 5099 * If the newly-added system app is an older version than the 5100 * already installed version, hide it. It will be scanned later 5101 * and re-added like an update. 5102 */ 5103 if (pkg.mVersionCode <= ps.versionCode) { 5104 shouldHideSystemApp = true; 5105 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 5106 + " but new version " + pkg.mVersionCode + " better than installed " 5107 + ps.versionCode + "; hiding system"); 5108 } else { 5109 /* 5110 * The newly found system app is a newer version that the 5111 * one previously installed. Simply remove the 5112 * already-installed application and replace it with our own 5113 * while keeping the application data. 5114 */ 5115 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5116 + " reverting from " + ps.codePathString + ": new version " 5117 + pkg.mVersionCode + " better than installed " + ps.versionCode); 5118 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5119 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 5120 getAppDexInstructionSets(ps)); 5121 synchronized (mInstallLock) { 5122 args.cleanUpResourcesLI(); 5123 } 5124 } 5125 } 5126 } 5127 5128 // The apk is forward locked (not public) if its code and resources 5129 // are kept in different files. (except for app in either system or 5130 // vendor path). 5131 // TODO grab this value from PackageSettings 5132 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5133 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 5134 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 5135 } 5136 } 5137 5138 // TODO: extend to support forward-locked splits 5139 String resourcePath = null; 5140 String baseResourcePath = null; 5141 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 5142 if (ps != null && ps.resourcePathString != null) { 5143 resourcePath = ps.resourcePathString; 5144 baseResourcePath = ps.resourcePathString; 5145 } else { 5146 // Should not happen at all. Just log an error. 5147 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 5148 } 5149 } else { 5150 resourcePath = pkg.codePath; 5151 baseResourcePath = pkg.baseCodePath; 5152 } 5153 5154 // Set application objects path explicitly. 5155 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 5156 pkg.applicationInfo.setCodePath(pkg.codePath); 5157 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 5158 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 5159 pkg.applicationInfo.setResourcePath(resourcePath); 5160 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 5161 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 5162 5163 // Note that we invoke the following method only if we are about to unpack an application 5164 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 5165 | SCAN_UPDATE_SIGNATURE, currentTime, user); 5166 5167 /* 5168 * If the system app should be overridden by a previously installed 5169 * data, hide the system app now and let the /data/app scan pick it up 5170 * again. 5171 */ 5172 if (shouldHideSystemApp) { 5173 synchronized (mPackages) { 5174 /* 5175 * We have to grant systems permissions before we hide, because 5176 * grantPermissions will assume the package update is trying to 5177 * expand its permissions. 5178 */ 5179 grantPermissionsLPw(pkg, true, pkg.packageName); 5180 mSettings.disableSystemPackageLPw(pkg.packageName); 5181 } 5182 } 5183 5184 return scannedPkg; 5185 } 5186 5187 private static String fixProcessName(String defProcessName, 5188 String processName, int uid) { 5189 if (processName == null) { 5190 return defProcessName; 5191 } 5192 return processName; 5193 } 5194 5195 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 5196 throws PackageManagerException { 5197 if (pkgSetting.signatures.mSignatures != null) { 5198 // Already existing package. Make sure signatures match 5199 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 5200 == PackageManager.SIGNATURE_MATCH; 5201 if (!match) { 5202 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 5203 == PackageManager.SIGNATURE_MATCH; 5204 } 5205 if (!match) { 5206 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 5207 == PackageManager.SIGNATURE_MATCH; 5208 } 5209 if (!match) { 5210 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5211 + pkg.packageName + " signatures do not match the " 5212 + "previously installed version; ignoring!"); 5213 } 5214 } 5215 5216 // Check for shared user signatures 5217 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 5218 // Already existing package. Make sure signatures match 5219 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5220 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 5221 if (!match) { 5222 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 5223 == PackageManager.SIGNATURE_MATCH; 5224 } 5225 if (!match) { 5226 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 5227 == PackageManager.SIGNATURE_MATCH; 5228 } 5229 if (!match) { 5230 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 5231 "Package " + pkg.packageName 5232 + " has no signatures that match those in shared user " 5233 + pkgSetting.sharedUser.name + "; ignoring!"); 5234 } 5235 } 5236 } 5237 5238 /** 5239 * Enforces that only the system UID or root's UID can call a method exposed 5240 * via Binder. 5241 * 5242 * @param message used as message if SecurityException is thrown 5243 * @throws SecurityException if the caller is not system or root 5244 */ 5245 private static final void enforceSystemOrRoot(String message) { 5246 final int uid = Binder.getCallingUid(); 5247 if (uid != Process.SYSTEM_UID && uid != 0) { 5248 throw new SecurityException(message); 5249 } 5250 } 5251 5252 @Override 5253 public void performBootDexOpt() { 5254 enforceSystemOrRoot("Only the system can request dexopt be performed"); 5255 5256 // Before everything else, see whether we need to fstrim. 5257 try { 5258 IMountService ms = PackageHelper.getMountService(); 5259 if (ms != null) { 5260 final boolean isUpgrade = isUpgrade(); 5261 boolean doTrim = isUpgrade; 5262 if (doTrim) { 5263 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 5264 } else { 5265 final long interval = android.provider.Settings.Global.getLong( 5266 mContext.getContentResolver(), 5267 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 5268 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 5269 if (interval > 0) { 5270 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 5271 if (timeSinceLast > interval) { 5272 doTrim = true; 5273 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 5274 + "; running immediately"); 5275 } 5276 } 5277 } 5278 if (doTrim) { 5279 if (!isFirstBoot()) { 5280 try { 5281 ActivityManagerNative.getDefault().showBootMessage( 5282 mContext.getResources().getString( 5283 R.string.android_upgrading_fstrim), true); 5284 } catch (RemoteException e) { 5285 } 5286 } 5287 ms.runMaintenance(); 5288 } 5289 } else { 5290 Slog.e(TAG, "Mount service unavailable!"); 5291 } 5292 } catch (RemoteException e) { 5293 // Can't happen; MountService is local 5294 } 5295 5296 final ArraySet<PackageParser.Package> pkgs; 5297 synchronized (mPackages) { 5298 pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages(); 5299 } 5300 5301 if (pkgs != null) { 5302 // Sort apps by importance for dexopt ordering. Important apps are given more priority 5303 // in case the device runs out of space. 5304 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 5305 // Give priority to core apps. 5306 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5307 PackageParser.Package pkg = it.next(); 5308 if (pkg.coreApp) { 5309 if (DEBUG_DEXOPT) { 5310 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 5311 } 5312 sortedPkgs.add(pkg); 5313 it.remove(); 5314 } 5315 } 5316 // Give priority to system apps that listen for pre boot complete. 5317 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 5318 ArraySet<String> pkgNames = getPackageNamesForIntent(intent); 5319 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5320 PackageParser.Package pkg = it.next(); 5321 if (pkgNames.contains(pkg.packageName)) { 5322 if (DEBUG_DEXOPT) { 5323 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 5324 } 5325 sortedPkgs.add(pkg); 5326 it.remove(); 5327 } 5328 } 5329 // Give priority to system apps. 5330 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5331 PackageParser.Package pkg = it.next(); 5332 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 5333 if (DEBUG_DEXOPT) { 5334 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName); 5335 } 5336 sortedPkgs.add(pkg); 5337 it.remove(); 5338 } 5339 } 5340 // Give priority to updated system apps. 5341 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5342 PackageParser.Package pkg = it.next(); 5343 if (pkg.isUpdatedSystemApp()) { 5344 if (DEBUG_DEXOPT) { 5345 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName); 5346 } 5347 sortedPkgs.add(pkg); 5348 it.remove(); 5349 } 5350 } 5351 // Give priority to apps that listen for boot complete. 5352 intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 5353 pkgNames = getPackageNamesForIntent(intent); 5354 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5355 PackageParser.Package pkg = it.next(); 5356 if (pkgNames.contains(pkg.packageName)) { 5357 if (DEBUG_DEXOPT) { 5358 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName); 5359 } 5360 sortedPkgs.add(pkg); 5361 it.remove(); 5362 } 5363 } 5364 // Filter out packages that aren't recently used. 5365 filterRecentlyUsedApps(pkgs); 5366 // Add all remaining apps. 5367 for (PackageParser.Package pkg : pkgs) { 5368 if (DEBUG_DEXOPT) { 5369 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 5370 } 5371 sortedPkgs.add(pkg); 5372 } 5373 5374 // If we want to be lazy, filter everything that wasn't recently used. 5375 if (mLazyDexOpt) { 5376 filterRecentlyUsedApps(sortedPkgs); 5377 } 5378 5379 int i = 0; 5380 int total = sortedPkgs.size(); 5381 File dataDir = Environment.getDataDirectory(); 5382 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 5383 if (lowThreshold == 0) { 5384 throw new IllegalStateException("Invalid low memory threshold"); 5385 } 5386 for (PackageParser.Package pkg : sortedPkgs) { 5387 long usableSpace = dataDir.getUsableSpace(); 5388 if (usableSpace < lowThreshold) { 5389 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 5390 break; 5391 } 5392 performBootDexOpt(pkg, ++i, total); 5393 } 5394 } 5395 } 5396 5397 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 5398 // Filter out packages that aren't recently used. 5399 // 5400 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 5401 // should do a full dexopt. 5402 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 5403 int total = pkgs.size(); 5404 int skipped = 0; 5405 long now = System.currentTimeMillis(); 5406 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 5407 PackageParser.Package pkg = i.next(); 5408 long then = pkg.mLastPackageUsageTimeInMills; 5409 if (then + mDexOptLRUThresholdInMills < now) { 5410 if (DEBUG_DEXOPT) { 5411 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 5412 ((then == 0) ? "never" : new Date(then))); 5413 } 5414 i.remove(); 5415 skipped++; 5416 } 5417 } 5418 if (DEBUG_DEXOPT) { 5419 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 5420 } 5421 } 5422 } 5423 5424 private ArraySet<String> getPackageNamesForIntent(Intent intent) { 5425 List<ResolveInfo> ris = null; 5426 try { 5427 ris = AppGlobals.getPackageManager().queryIntentReceivers( 5428 intent, null, 0, UserHandle.USER_OWNER); 5429 } catch (RemoteException e) { 5430 } 5431 ArraySet<String> pkgNames = new ArraySet<String>(); 5432 if (ris != null) { 5433 for (ResolveInfo ri : ris) { 5434 pkgNames.add(ri.activityInfo.packageName); 5435 } 5436 } 5437 return pkgNames; 5438 } 5439 5440 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 5441 if (DEBUG_DEXOPT) { 5442 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 5443 } 5444 if (!isFirstBoot()) { 5445 try { 5446 ActivityManagerNative.getDefault().showBootMessage( 5447 mContext.getResources().getString(R.string.android_upgrading_apk, 5448 curr, total), true); 5449 } catch (RemoteException e) { 5450 } 5451 } 5452 PackageParser.Package p = pkg; 5453 synchronized (mInstallLock) { 5454 mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, 5455 false /* force dex */, false /* defer */, true /* include dependencies */); 5456 } 5457 } 5458 5459 @Override 5460 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 5461 return performDexOpt(packageName, instructionSet, false); 5462 } 5463 5464 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) { 5465 boolean dexopt = mLazyDexOpt || backgroundDexopt; 5466 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 5467 if (!dexopt && !updateUsage) { 5468 // We aren't going to dexopt or update usage, so bail early. 5469 return false; 5470 } 5471 PackageParser.Package p; 5472 final String targetInstructionSet; 5473 synchronized (mPackages) { 5474 p = mPackages.get(packageName); 5475 if (p == null) { 5476 return false; 5477 } 5478 if (updateUsage) { 5479 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 5480 } 5481 mPackageUsage.write(false); 5482 if (!dexopt) { 5483 // We aren't going to dexopt, so bail early. 5484 return false; 5485 } 5486 5487 targetInstructionSet = instructionSet != null ? instructionSet : 5488 getPrimaryInstructionSet(p.applicationInfo); 5489 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 5490 return false; 5491 } 5492 } 5493 5494 synchronized (mInstallLock) { 5495 final String[] instructionSets = new String[] { targetInstructionSet }; 5496 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, 5497 false /* forceDex */, false /* defer */, true /* inclDependencies */); 5498 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 5499 } 5500 } 5501 5502 public ArraySet<String> getPackagesThatNeedDexOpt() { 5503 ArraySet<String> pkgs = null; 5504 synchronized (mPackages) { 5505 for (PackageParser.Package p : mPackages.values()) { 5506 if (DEBUG_DEXOPT) { 5507 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 5508 } 5509 if (!p.mDexOptPerformed.isEmpty()) { 5510 continue; 5511 } 5512 if (pkgs == null) { 5513 pkgs = new ArraySet<String>(); 5514 } 5515 pkgs.add(p.packageName); 5516 } 5517 } 5518 return pkgs; 5519 } 5520 5521 public void shutdown() { 5522 mPackageUsage.write(true); 5523 } 5524 5525 @Override 5526 public void forceDexOpt(String packageName) { 5527 enforceSystemOrRoot("forceDexOpt"); 5528 5529 PackageParser.Package pkg; 5530 synchronized (mPackages) { 5531 pkg = mPackages.get(packageName); 5532 if (pkg == null) { 5533 throw new IllegalArgumentException("Missing package: " + packageName); 5534 } 5535 } 5536 5537 synchronized (mInstallLock) { 5538 final String[] instructionSets = new String[] { 5539 getPrimaryInstructionSet(pkg.applicationInfo) }; 5540 final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, 5541 true /*forceDex*/, false /* defer */, true /* inclDependencies */); 5542 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 5543 throw new IllegalStateException("Failed to dexopt: " + res); 5544 } 5545 } 5546 } 5547 5548 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 5549 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 5550 Slog.w(TAG, "Unable to update from " + oldPkg.name 5551 + " to " + newPkg.packageName 5552 + ": old package not in system partition"); 5553 return false; 5554 } else if (mPackages.get(oldPkg.name) != null) { 5555 Slog.w(TAG, "Unable to update from " + oldPkg.name 5556 + " to " + newPkg.packageName 5557 + ": old package still exists"); 5558 return false; 5559 } 5560 return true; 5561 } 5562 5563 private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) { 5564 int[] users = sUserManager.getUserIds(); 5565 int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo); 5566 if (res < 0) { 5567 return res; 5568 } 5569 for (int user : users) { 5570 if (user != 0) { 5571 res = mInstaller.createUserData(volumeUuid, packageName, 5572 UserHandle.getUid(user, uid), user, seinfo); 5573 if (res < 0) { 5574 return res; 5575 } 5576 } 5577 } 5578 return res; 5579 } 5580 5581 private int removeDataDirsLI(String volumeUuid, String packageName) { 5582 int[] users = sUserManager.getUserIds(); 5583 int res = 0; 5584 for (int user : users) { 5585 int resInner = mInstaller.remove(volumeUuid, packageName, user); 5586 if (resInner < 0) { 5587 res = resInner; 5588 } 5589 } 5590 5591 return res; 5592 } 5593 5594 private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 5595 int[] users = sUserManager.getUserIds(); 5596 int res = 0; 5597 for (int user : users) { 5598 int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user); 5599 if (resInner < 0) { 5600 res = resInner; 5601 } 5602 } 5603 return res; 5604 } 5605 5606 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 5607 PackageParser.Package changingLib) { 5608 if (file.path != null) { 5609 usesLibraryFiles.add(file.path); 5610 return; 5611 } 5612 PackageParser.Package p = mPackages.get(file.apk); 5613 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 5614 // If we are doing this while in the middle of updating a library apk, 5615 // then we need to make sure to use that new apk for determining the 5616 // dependencies here. (We haven't yet finished committing the new apk 5617 // to the package manager state.) 5618 if (p == null || p.packageName.equals(changingLib.packageName)) { 5619 p = changingLib; 5620 } 5621 } 5622 if (p != null) { 5623 usesLibraryFiles.addAll(p.getAllCodePaths()); 5624 } 5625 } 5626 5627 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 5628 PackageParser.Package changingLib) throws PackageManagerException { 5629 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 5630 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 5631 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 5632 for (int i=0; i<N; i++) { 5633 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 5634 if (file == null) { 5635 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 5636 "Package " + pkg.packageName + " requires unavailable shared library " 5637 + pkg.usesLibraries.get(i) + "; failing!"); 5638 } 5639 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5640 } 5641 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 5642 for (int i=0; i<N; i++) { 5643 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 5644 if (file == null) { 5645 Slog.w(TAG, "Package " + pkg.packageName 5646 + " desires unavailable shared library " 5647 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 5648 } else { 5649 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5650 } 5651 } 5652 N = usesLibraryFiles.size(); 5653 if (N > 0) { 5654 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 5655 } else { 5656 pkg.usesLibraryFiles = null; 5657 } 5658 } 5659 } 5660 5661 private static boolean hasString(List<String> list, List<String> which) { 5662 if (list == null) { 5663 return false; 5664 } 5665 for (int i=list.size()-1; i>=0; i--) { 5666 for (int j=which.size()-1; j>=0; j--) { 5667 if (which.get(j).equals(list.get(i))) { 5668 return true; 5669 } 5670 } 5671 } 5672 return false; 5673 } 5674 5675 private void updateAllSharedLibrariesLPw() { 5676 for (PackageParser.Package pkg : mPackages.values()) { 5677 try { 5678 updateSharedLibrariesLPw(pkg, null); 5679 } catch (PackageManagerException e) { 5680 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5681 } 5682 } 5683 } 5684 5685 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 5686 PackageParser.Package changingPkg) { 5687 ArrayList<PackageParser.Package> res = null; 5688 for (PackageParser.Package pkg : mPackages.values()) { 5689 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 5690 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 5691 if (res == null) { 5692 res = new ArrayList<PackageParser.Package>(); 5693 } 5694 res.add(pkg); 5695 try { 5696 updateSharedLibrariesLPw(pkg, changingPkg); 5697 } catch (PackageManagerException e) { 5698 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5699 } 5700 } 5701 } 5702 return res; 5703 } 5704 5705 /** 5706 * Derive the value of the {@code cpuAbiOverride} based on the provided 5707 * value and an optional stored value from the package settings. 5708 */ 5709 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 5710 String cpuAbiOverride = null; 5711 5712 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 5713 cpuAbiOverride = null; 5714 } else if (abiOverride != null) { 5715 cpuAbiOverride = abiOverride; 5716 } else if (settings != null) { 5717 cpuAbiOverride = settings.cpuAbiOverrideString; 5718 } 5719 5720 return cpuAbiOverride; 5721 } 5722 5723 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 5724 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5725 boolean success = false; 5726 try { 5727 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 5728 currentTime, user); 5729 success = true; 5730 return res; 5731 } finally { 5732 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5733 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 5734 } 5735 } 5736 } 5737 5738 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 5739 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5740 final File scanFile = new File(pkg.codePath); 5741 if (pkg.applicationInfo.getCodePath() == null || 5742 pkg.applicationInfo.getResourcePath() == null) { 5743 // Bail out. The resource and code paths haven't been set. 5744 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 5745 "Code and resource paths haven't been set correctly"); 5746 } 5747 5748 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5749 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 5750 } else { 5751 // Only allow system apps to be flagged as core apps. 5752 pkg.coreApp = false; 5753 } 5754 5755 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 5756 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5757 } 5758 5759 if (mCustomResolverComponentName != null && 5760 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 5761 setUpCustomResolverActivity(pkg); 5762 } 5763 5764 if (pkg.packageName.equals("android")) { 5765 synchronized (mPackages) { 5766 if (mAndroidApplication != null) { 5767 Slog.w(TAG, "*************************************************"); 5768 Slog.w(TAG, "Core android package being redefined. Skipping."); 5769 Slog.w(TAG, " file=" + scanFile); 5770 Slog.w(TAG, "*************************************************"); 5771 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5772 "Core android package being redefined. Skipping."); 5773 } 5774 5775 // Set up information for our fall-back user intent resolution activity. 5776 mPlatformPackage = pkg; 5777 pkg.mVersionCode = mSdkVersion; 5778 mAndroidApplication = pkg.applicationInfo; 5779 5780 if (!mResolverReplaced) { 5781 mResolveActivity.applicationInfo = mAndroidApplication; 5782 mResolveActivity.name = ResolverActivity.class.getName(); 5783 mResolveActivity.packageName = mAndroidApplication.packageName; 5784 mResolveActivity.processName = "system:ui"; 5785 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5786 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 5787 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 5788 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 5789 mResolveActivity.exported = true; 5790 mResolveActivity.enabled = true; 5791 mResolveInfo.activityInfo = mResolveActivity; 5792 mResolveInfo.priority = 0; 5793 mResolveInfo.preferredOrder = 0; 5794 mResolveInfo.match = 0; 5795 mResolveComponentName = new ComponentName( 5796 mAndroidApplication.packageName, mResolveActivity.name); 5797 } 5798 } 5799 } 5800 5801 if (DEBUG_PACKAGE_SCANNING) { 5802 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5803 Log.d(TAG, "Scanning package " + pkg.packageName); 5804 } 5805 5806 if (mPackages.containsKey(pkg.packageName) 5807 || mSharedLibraries.containsKey(pkg.packageName)) { 5808 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5809 "Application package " + pkg.packageName 5810 + " already installed. Skipping duplicate."); 5811 } 5812 5813 // If we're only installing presumed-existing packages, require that the 5814 // scanned APK is both already known and at the path previously established 5815 // for it. Previously unknown packages we pick up normally, but if we have an 5816 // a priori expectation about this package's install presence, enforce it. 5817 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 5818 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 5819 if (known != null) { 5820 if (DEBUG_PACKAGE_SCANNING) { 5821 Log.d(TAG, "Examining " + pkg.codePath 5822 + " and requiring known paths " + known.codePathString 5823 + " & " + known.resourcePathString); 5824 } 5825 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 5826 || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { 5827 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 5828 "Application package " + pkg.packageName 5829 + " found at " + pkg.applicationInfo.getCodePath() 5830 + " but expected at " + known.codePathString + "; ignoring."); 5831 } 5832 } 5833 } 5834 5835 // Initialize package source and resource directories 5836 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 5837 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 5838 5839 SharedUserSetting suid = null; 5840 PackageSetting pkgSetting = null; 5841 5842 if (!isSystemApp(pkg)) { 5843 // Only system apps can use these features. 5844 pkg.mOriginalPackages = null; 5845 pkg.mRealPackage = null; 5846 pkg.mAdoptPermissions = null; 5847 } 5848 5849 // writer 5850 synchronized (mPackages) { 5851 if (pkg.mSharedUserId != null) { 5852 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 5853 if (suid == null) { 5854 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5855 "Creating application package " + pkg.packageName 5856 + " for shared user failed"); 5857 } 5858 if (DEBUG_PACKAGE_SCANNING) { 5859 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5860 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 5861 + "): packages=" + suid.packages); 5862 } 5863 } 5864 5865 // Check if we are renaming from an original package name. 5866 PackageSetting origPackage = null; 5867 String realName = null; 5868 if (pkg.mOriginalPackages != null) { 5869 // This package may need to be renamed to a previously 5870 // installed name. Let's check on that... 5871 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 5872 if (pkg.mOriginalPackages.contains(renamed)) { 5873 // This package had originally been installed as the 5874 // original name, and we have already taken care of 5875 // transitioning to the new one. Just update the new 5876 // one to continue using the old name. 5877 realName = pkg.mRealPackage; 5878 if (!pkg.packageName.equals(renamed)) { 5879 // Callers into this function may have already taken 5880 // care of renaming the package; only do it here if 5881 // it is not already done. 5882 pkg.setPackageName(renamed); 5883 } 5884 5885 } else { 5886 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 5887 if ((origPackage = mSettings.peekPackageLPr( 5888 pkg.mOriginalPackages.get(i))) != null) { 5889 // We do have the package already installed under its 5890 // original name... should we use it? 5891 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 5892 // New package is not compatible with original. 5893 origPackage = null; 5894 continue; 5895 } else if (origPackage.sharedUser != null) { 5896 // Make sure uid is compatible between packages. 5897 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 5898 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 5899 + " to " + pkg.packageName + ": old uid " 5900 + origPackage.sharedUser.name 5901 + " differs from " + pkg.mSharedUserId); 5902 origPackage = null; 5903 continue; 5904 } 5905 } else { 5906 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 5907 + pkg.packageName + " to old name " + origPackage.name); 5908 } 5909 break; 5910 } 5911 } 5912 } 5913 } 5914 5915 if (mTransferedPackages.contains(pkg.packageName)) { 5916 Slog.w(TAG, "Package " + pkg.packageName 5917 + " was transferred to another, but its .apk remains"); 5918 } 5919 5920 // Just create the setting, don't add it yet. For already existing packages 5921 // the PkgSetting exists already and doesn't have to be created. 5922 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 5923 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 5924 pkg.applicationInfo.primaryCpuAbi, 5925 pkg.applicationInfo.secondaryCpuAbi, 5926 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 5927 user, false); 5928 if (pkgSetting == null) { 5929 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5930 "Creating application package " + pkg.packageName + " failed"); 5931 } 5932 5933 if (pkgSetting.origPackage != null) { 5934 // If we are first transitioning from an original package, 5935 // fix up the new package's name now. We need to do this after 5936 // looking up the package under its new name, so getPackageLP 5937 // can take care of fiddling things correctly. 5938 pkg.setPackageName(origPackage.name); 5939 5940 // File a report about this. 5941 String msg = "New package " + pkgSetting.realName 5942 + " renamed to replace old package " + pkgSetting.name; 5943 reportSettingsProblem(Log.WARN, msg); 5944 5945 // Make a note of it. 5946 mTransferedPackages.add(origPackage.name); 5947 5948 // No longer need to retain this. 5949 pkgSetting.origPackage = null; 5950 } 5951 5952 if (realName != null) { 5953 // Make a note of it. 5954 mTransferedPackages.add(pkg.packageName); 5955 } 5956 5957 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 5958 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 5959 } 5960 5961 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5962 // Check all shared libraries and map to their actual file path. 5963 // We only do this here for apps not on a system dir, because those 5964 // are the only ones that can fail an install due to this. We 5965 // will take care of the system apps by updating all of their 5966 // library paths after the scan is done. 5967 updateSharedLibrariesLPw(pkg, null); 5968 } 5969 5970 if (mFoundPolicyFile) { 5971 SELinuxMMAC.assignSeinfoValue(pkg); 5972 } 5973 5974 pkg.applicationInfo.uid = pkgSetting.appId; 5975 pkg.mExtras = pkgSetting; 5976 if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) { 5977 try { 5978 verifySignaturesLP(pkgSetting, pkg); 5979 // We just determined the app is signed correctly, so bring 5980 // over the latest parsed certs. 5981 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5982 } catch (PackageManagerException e) { 5983 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5984 throw e; 5985 } 5986 // The signature has changed, but this package is in the system 5987 // image... let's recover! 5988 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5989 // However... if this package is part of a shared user, but it 5990 // doesn't match the signature of the shared user, let's fail. 5991 // What this means is that you can't change the signatures 5992 // associated with an overall shared user, which doesn't seem all 5993 // that unreasonable. 5994 if (pkgSetting.sharedUser != null) { 5995 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5996 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 5997 throw new PackageManagerException( 5998 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 5999 "Signature mismatch for shared user : " 6000 + pkgSetting.sharedUser); 6001 } 6002 } 6003 // File a report about this. 6004 String msg = "System package " + pkg.packageName 6005 + " signature changed; retaining data."; 6006 reportSettingsProblem(Log.WARN, msg); 6007 } 6008 } else { 6009 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) { 6010 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6011 + pkg.packageName + " upgrade keys do not match the " 6012 + "previously installed version"); 6013 } else { 6014 // We just determined the app is signed correctly, so bring 6015 // over the latest parsed certs. 6016 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6017 } 6018 } 6019 // Verify that this new package doesn't have any content providers 6020 // that conflict with existing packages. Only do this if the 6021 // package isn't already installed, since we don't want to break 6022 // things that are installed. 6023 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 6024 final int N = pkg.providers.size(); 6025 int i; 6026 for (i=0; i<N; i++) { 6027 PackageParser.Provider p = pkg.providers.get(i); 6028 if (p.info.authority != null) { 6029 String names[] = p.info.authority.split(";"); 6030 for (int j = 0; j < names.length; j++) { 6031 if (mProvidersByAuthority.containsKey(names[j])) { 6032 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6033 final String otherPackageName = 6034 ((other != null && other.getComponentName() != null) ? 6035 other.getComponentName().getPackageName() : "?"); 6036 throw new PackageManagerException( 6037 INSTALL_FAILED_CONFLICTING_PROVIDER, 6038 "Can't install because provider name " + names[j] 6039 + " (in package " + pkg.applicationInfo.packageName 6040 + ") is already used by " + otherPackageName); 6041 } 6042 } 6043 } 6044 } 6045 } 6046 6047 if (pkg.mAdoptPermissions != null) { 6048 // This package wants to adopt ownership of permissions from 6049 // another package. 6050 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 6051 final String origName = pkg.mAdoptPermissions.get(i); 6052 final PackageSetting orig = mSettings.peekPackageLPr(origName); 6053 if (orig != null) { 6054 if (verifyPackageUpdateLPr(orig, pkg)) { 6055 Slog.i(TAG, "Adopting permissions from " + origName + " to " 6056 + pkg.packageName); 6057 mSettings.transferPermissionsLPw(origName, pkg.packageName); 6058 } 6059 } 6060 } 6061 } 6062 } 6063 6064 final String pkgName = pkg.packageName; 6065 6066 final long scanFileTime = scanFile.lastModified(); 6067 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 6068 pkg.applicationInfo.processName = fixProcessName( 6069 pkg.applicationInfo.packageName, 6070 pkg.applicationInfo.processName, 6071 pkg.applicationInfo.uid); 6072 6073 File dataPath; 6074 if (mPlatformPackage == pkg) { 6075 // The system package is special. 6076 dataPath = new File(Environment.getDataDirectory(), "system"); 6077 6078 pkg.applicationInfo.dataDir = dataPath.getPath(); 6079 6080 } else { 6081 // This is a normal package, need to make its data directory. 6082 dataPath = PackageManager.getDataDirForUser(pkg.volumeUuid, pkg.packageName, 6083 UserHandle.USER_OWNER); 6084 6085 boolean uidError = false; 6086 if (dataPath.exists()) { 6087 int currentUid = 0; 6088 try { 6089 StructStat stat = Os.stat(dataPath.getPath()); 6090 currentUid = stat.st_uid; 6091 } catch (ErrnoException e) { 6092 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 6093 } 6094 6095 // If we have mismatched owners for the data path, we have a problem. 6096 if (currentUid != pkg.applicationInfo.uid) { 6097 boolean recovered = false; 6098 if (currentUid == 0) { 6099 // The directory somehow became owned by root. Wow. 6100 // This is probably because the system was stopped while 6101 // installd was in the middle of messing with its libs 6102 // directory. Ask installd to fix that. 6103 int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName, 6104 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 6105 if (ret >= 0) { 6106 recovered = true; 6107 String msg = "Package " + pkg.packageName 6108 + " unexpectedly changed to uid 0; recovered to " + 6109 + pkg.applicationInfo.uid; 6110 reportSettingsProblem(Log.WARN, msg); 6111 } 6112 } 6113 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6114 || (scanFlags&SCAN_BOOTING) != 0)) { 6115 // If this is a system app, we can at least delete its 6116 // current data so the application will still work. 6117 int ret = removeDataDirsLI(pkg.volumeUuid, pkgName); 6118 if (ret >= 0) { 6119 // TODO: Kill the processes first 6120 // Old data gone! 6121 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6122 ? "System package " : "Third party package "; 6123 String msg = prefix + pkg.packageName 6124 + " has changed from uid: " 6125 + currentUid + " to " 6126 + pkg.applicationInfo.uid + "; old data erased"; 6127 reportSettingsProblem(Log.WARN, msg); 6128 recovered = true; 6129 6130 // And now re-install the app. 6131 ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6132 pkg.applicationInfo.seinfo); 6133 if (ret == -1) { 6134 // Ack should not happen! 6135 msg = prefix + pkg.packageName 6136 + " could not have data directory re-created after delete."; 6137 reportSettingsProblem(Log.WARN, msg); 6138 throw new PackageManagerException( 6139 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 6140 } 6141 } 6142 if (!recovered) { 6143 mHasSystemUidErrors = true; 6144 } 6145 } else if (!recovered) { 6146 // If we allow this install to proceed, we will be broken. 6147 // Abort, abort! 6148 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 6149 "scanPackageLI"); 6150 } 6151 if (!recovered) { 6152 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 6153 + pkg.applicationInfo.uid + "/fs_" 6154 + currentUid; 6155 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 6156 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 6157 String msg = "Package " + pkg.packageName 6158 + " has mismatched uid: " 6159 + currentUid + " on disk, " 6160 + pkg.applicationInfo.uid + " in settings"; 6161 // writer 6162 synchronized (mPackages) { 6163 mSettings.mReadMessages.append(msg); 6164 mSettings.mReadMessages.append('\n'); 6165 uidError = true; 6166 if (!pkgSetting.uidError) { 6167 reportSettingsProblem(Log.ERROR, msg); 6168 } 6169 } 6170 } 6171 } 6172 pkg.applicationInfo.dataDir = dataPath.getPath(); 6173 if (mShouldRestoreconData) { 6174 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 6175 mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName, 6176 pkg.applicationInfo.seinfo, pkg.applicationInfo.uid); 6177 } 6178 } else { 6179 if (DEBUG_PACKAGE_SCANNING) { 6180 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6181 Log.v(TAG, "Want this data dir: " + dataPath); 6182 } 6183 //invoke installer to do the actual installation 6184 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6185 pkg.applicationInfo.seinfo); 6186 if (ret < 0) { 6187 // Error from installer 6188 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6189 "Unable to create data dirs [errorCode=" + ret + "]"); 6190 } 6191 6192 if (dataPath.exists()) { 6193 pkg.applicationInfo.dataDir = dataPath.getPath(); 6194 } else { 6195 Slog.w(TAG, "Unable to create data directory: " + dataPath); 6196 pkg.applicationInfo.dataDir = null; 6197 } 6198 } 6199 6200 pkgSetting.uidError = uidError; 6201 } 6202 6203 final String path = scanFile.getPath(); 6204 final String codePath = pkg.applicationInfo.getCodePath(); 6205 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 6206 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 6207 setBundledAppAbisAndRoots(pkg, pkgSetting); 6208 6209 // If we haven't found any native libraries for the app, check if it has 6210 // renderscript code. We'll need to force the app to 32 bit if it has 6211 // renderscript bitcode. 6212 if (pkg.applicationInfo.primaryCpuAbi == null 6213 && pkg.applicationInfo.secondaryCpuAbi == null 6214 && Build.SUPPORTED_64_BIT_ABIS.length > 0) { 6215 NativeLibraryHelper.Handle handle = null; 6216 try { 6217 handle = NativeLibraryHelper.Handle.create(scanFile); 6218 if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 6219 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6220 } 6221 } catch (IOException ioe) { 6222 Slog.w(TAG, "Error scanning system app : " + ioe); 6223 } finally { 6224 IoUtils.closeQuietly(handle); 6225 } 6226 } 6227 6228 setNativeLibraryPaths(pkg); 6229 } else { 6230 // TODO: We can probably be smarter about this stuff. For installed apps, 6231 // we can calculate this information at install time once and for all. For 6232 // system apps, we can probably assume that this information doesn't change 6233 // after the first boot scan. As things stand, we do lots of unnecessary work. 6234 6235 // Give ourselves some initial paths; we'll come back for another 6236 // pass once we've determined ABI below. 6237 setNativeLibraryPaths(pkg); 6238 6239 final boolean isAsec = pkg.isForwardLocked() || isExternal(pkg); 6240 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 6241 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 6242 6243 NativeLibraryHelper.Handle handle = null; 6244 try { 6245 handle = NativeLibraryHelper.Handle.create(scanFile); 6246 // TODO(multiArch): This can be null for apps that didn't go through the 6247 // usual installation process. We can calculate it again, like we 6248 // do during install time. 6249 // 6250 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 6251 // unnecessary. 6252 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 6253 6254 // Null out the abis so that they can be recalculated. 6255 pkg.applicationInfo.primaryCpuAbi = null; 6256 pkg.applicationInfo.secondaryCpuAbi = null; 6257 if (isMultiArch(pkg.applicationInfo)) { 6258 // Warn if we've set an abiOverride for multi-lib packages.. 6259 // By definition, we need to copy both 32 and 64 bit libraries for 6260 // such packages. 6261 if (pkg.cpuAbiOverride != null 6262 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 6263 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 6264 } 6265 6266 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 6267 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 6268 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 6269 if (isAsec) { 6270 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 6271 } else { 6272 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6273 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 6274 useIsaSpecificSubdirs); 6275 } 6276 } 6277 6278 maybeThrowExceptionForMultiArchCopy( 6279 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 6280 6281 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 6282 if (isAsec) { 6283 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 6284 } else { 6285 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6286 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 6287 useIsaSpecificSubdirs); 6288 } 6289 } 6290 6291 maybeThrowExceptionForMultiArchCopy( 6292 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 6293 6294 if (abi64 >= 0) { 6295 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 6296 } 6297 6298 if (abi32 >= 0) { 6299 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 6300 if (abi64 >= 0) { 6301 pkg.applicationInfo.secondaryCpuAbi = abi; 6302 } else { 6303 pkg.applicationInfo.primaryCpuAbi = abi; 6304 } 6305 } 6306 } else { 6307 String[] abiList = (cpuAbiOverride != null) ? 6308 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 6309 6310 // Enable gross and lame hacks for apps that are built with old 6311 // SDK tools. We must scan their APKs for renderscript bitcode and 6312 // not launch them if it's present. Don't bother checking on devices 6313 // that don't have 64 bit support. 6314 boolean needsRenderScriptOverride = false; 6315 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 6316 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 6317 abiList = Build.SUPPORTED_32_BIT_ABIS; 6318 needsRenderScriptOverride = true; 6319 } 6320 6321 final int copyRet; 6322 if (isAsec) { 6323 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 6324 } else { 6325 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6326 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 6327 } 6328 6329 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 6330 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 6331 "Error unpackaging native libs for app, errorCode=" + copyRet); 6332 } 6333 6334 if (copyRet >= 0) { 6335 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 6336 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 6337 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 6338 } else if (needsRenderScriptOverride) { 6339 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 6340 } 6341 } 6342 } catch (IOException ioe) { 6343 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 6344 } finally { 6345 IoUtils.closeQuietly(handle); 6346 } 6347 6348 // Now that we've calculated the ABIs and determined if it's an internal app, 6349 // we will go ahead and populate the nativeLibraryPath. 6350 setNativeLibraryPaths(pkg); 6351 6352 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 6353 final int[] userIds = sUserManager.getUserIds(); 6354 synchronized (mInstallLock) { 6355 // Create a native library symlink only if we have native libraries 6356 // and if the native libraries are 32 bit libraries. We do not provide 6357 // this symlink for 64 bit libraries. 6358 if (pkg.applicationInfo.primaryCpuAbi != null && 6359 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 6360 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 6361 for (int userId : userIds) { 6362 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 6363 nativeLibPath, userId) < 0) { 6364 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 6365 "Failed linking native library dir (user=" + userId + ")"); 6366 } 6367 } 6368 } 6369 } 6370 } 6371 6372 // This is a special case for the "system" package, where the ABI is 6373 // dictated by the zygote configuration (and init.rc). We should keep track 6374 // of this ABI so that we can deal with "normal" applications that run under 6375 // the same UID correctly. 6376 if (mPlatformPackage == pkg) { 6377 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 6378 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 6379 } 6380 6381 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 6382 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 6383 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 6384 // Copy the derived override back to the parsed package, so that we can 6385 // update the package settings accordingly. 6386 pkg.cpuAbiOverride = cpuAbiOverride; 6387 6388 if (DEBUG_ABI_SELECTION) { 6389 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 6390 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 6391 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 6392 } 6393 6394 // Push the derived path down into PackageSettings so we know what to 6395 // clean up at uninstall time. 6396 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 6397 6398 if (DEBUG_ABI_SELECTION) { 6399 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 6400 " primary=" + pkg.applicationInfo.primaryCpuAbi + 6401 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 6402 } 6403 6404 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 6405 // We don't do this here during boot because we can do it all 6406 // at once after scanning all existing packages. 6407 // 6408 // We also do this *before* we perform dexopt on this package, so that 6409 // we can avoid redundant dexopts, and also to make sure we've got the 6410 // code and package path correct. 6411 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 6412 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); 6413 } 6414 6415 if ((scanFlags & SCAN_NO_DEX) == 0) { 6416 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, 6417 forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */); 6418 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6419 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 6420 } 6421 } 6422 if (mFactoryTest && pkg.requestedPermissions.contains( 6423 android.Manifest.permission.FACTORY_TEST)) { 6424 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 6425 } 6426 6427 ArrayList<PackageParser.Package> clientLibPkgs = null; 6428 6429 // writer 6430 synchronized (mPackages) { 6431 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6432 // Only system apps can add new shared libraries. 6433 if (pkg.libraryNames != null) { 6434 for (int i=0; i<pkg.libraryNames.size(); i++) { 6435 String name = pkg.libraryNames.get(i); 6436 boolean allowed = false; 6437 if (pkg.isUpdatedSystemApp()) { 6438 // New library entries can only be added through the 6439 // system image. This is important to get rid of a lot 6440 // of nasty edge cases: for example if we allowed a non- 6441 // system update of the app to add a library, then uninstalling 6442 // the update would make the library go away, and assumptions 6443 // we made such as through app install filtering would now 6444 // have allowed apps on the device which aren't compatible 6445 // with it. Better to just have the restriction here, be 6446 // conservative, and create many fewer cases that can negatively 6447 // impact the user experience. 6448 final PackageSetting sysPs = mSettings 6449 .getDisabledSystemPkgLPr(pkg.packageName); 6450 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 6451 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 6452 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 6453 allowed = true; 6454 allowed = true; 6455 break; 6456 } 6457 } 6458 } 6459 } else { 6460 allowed = true; 6461 } 6462 if (allowed) { 6463 if (!mSharedLibraries.containsKey(name)) { 6464 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 6465 } else if (!name.equals(pkg.packageName)) { 6466 Slog.w(TAG, "Package " + pkg.packageName + " library " 6467 + name + " already exists; skipping"); 6468 } 6469 } else { 6470 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 6471 + name + " that is not declared on system image; skipping"); 6472 } 6473 } 6474 if ((scanFlags&SCAN_BOOTING) == 0) { 6475 // If we are not booting, we need to update any applications 6476 // that are clients of our shared library. If we are booting, 6477 // this will all be done once the scan is complete. 6478 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 6479 } 6480 } 6481 } 6482 } 6483 6484 // We also need to dexopt any apps that are dependent on this library. Note that 6485 // if these fail, we should abort the install since installing the library will 6486 // result in some apps being broken. 6487 if (clientLibPkgs != null) { 6488 if ((scanFlags & SCAN_NO_DEX) == 0) { 6489 for (int i = 0; i < clientLibPkgs.size(); i++) { 6490 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6491 int result = mPackageDexOptimizer.performDexOpt(clientPkg, 6492 null /* instruction sets */, forceDex, 6493 (scanFlags & SCAN_DEFER_DEX) != 0, false); 6494 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6495 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 6496 "scanPackageLI failed to dexopt clientLibPkgs"); 6497 } 6498 } 6499 } 6500 } 6501 6502 // Also need to kill any apps that are dependent on the library. 6503 if (clientLibPkgs != null) { 6504 for (int i=0; i<clientLibPkgs.size(); i++) { 6505 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6506 killApplication(clientPkg.applicationInfo.packageName, 6507 clientPkg.applicationInfo.uid, "update lib"); 6508 } 6509 } 6510 6511 // writer 6512 synchronized (mPackages) { 6513 // We don't expect installation to fail beyond this point 6514 6515 // Add the new setting to mSettings 6516 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 6517 // Add the new setting to mPackages 6518 mPackages.put(pkg.applicationInfo.packageName, pkg); 6519 // Make sure we don't accidentally delete its data. 6520 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 6521 while (iter.hasNext()) { 6522 PackageCleanItem item = iter.next(); 6523 if (pkgName.equals(item.packageName)) { 6524 iter.remove(); 6525 } 6526 } 6527 6528 // Take care of first install / last update times. 6529 if (currentTime != 0) { 6530 if (pkgSetting.firstInstallTime == 0) { 6531 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 6532 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 6533 pkgSetting.lastUpdateTime = currentTime; 6534 } 6535 } else if (pkgSetting.firstInstallTime == 0) { 6536 // We need *something*. Take time time stamp of the file. 6537 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 6538 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 6539 if (scanFileTime != pkgSetting.timeStamp) { 6540 // A package on the system image has changed; consider this 6541 // to be an update. 6542 pkgSetting.lastUpdateTime = scanFileTime; 6543 } 6544 } 6545 6546 // Add the package's KeySets to the global KeySetManagerService 6547 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6548 try { 6549 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys); 6550 if (pkg.mKeySetMapping != null) { 6551 ksms.addDefinedKeySetsToPackageLPw(pkg.packageName, pkg.mKeySetMapping); 6552 if (pkg.mUpgradeKeySets != null) { 6553 ksms.addUpgradeKeySetsToPackageLPw(pkg.packageName, pkg.mUpgradeKeySets); 6554 } 6555 } 6556 } catch (NullPointerException e) { 6557 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 6558 } catch (IllegalArgumentException e) { 6559 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 6560 } 6561 6562 int N = pkg.providers.size(); 6563 StringBuilder r = null; 6564 int i; 6565 for (i=0; i<N; i++) { 6566 PackageParser.Provider p = pkg.providers.get(i); 6567 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 6568 p.info.processName, pkg.applicationInfo.uid); 6569 mProviders.addProvider(p); 6570 p.syncable = p.info.isSyncable; 6571 if (p.info.authority != null) { 6572 String names[] = p.info.authority.split(";"); 6573 p.info.authority = null; 6574 for (int j = 0; j < names.length; j++) { 6575 if (j == 1 && p.syncable) { 6576 // We only want the first authority for a provider to possibly be 6577 // syncable, so if we already added this provider using a different 6578 // authority clear the syncable flag. We copy the provider before 6579 // changing it because the mProviders object contains a reference 6580 // to a provider that we don't want to change. 6581 // Only do this for the second authority since the resulting provider 6582 // object can be the same for all future authorities for this provider. 6583 p = new PackageParser.Provider(p); 6584 p.syncable = false; 6585 } 6586 if (!mProvidersByAuthority.containsKey(names[j])) { 6587 mProvidersByAuthority.put(names[j], p); 6588 if (p.info.authority == null) { 6589 p.info.authority = names[j]; 6590 } else { 6591 p.info.authority = p.info.authority + ";" + names[j]; 6592 } 6593 if (DEBUG_PACKAGE_SCANNING) { 6594 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6595 Log.d(TAG, "Registered content provider: " + names[j] 6596 + ", className = " + p.info.name + ", isSyncable = " 6597 + p.info.isSyncable); 6598 } 6599 } else { 6600 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6601 Slog.w(TAG, "Skipping provider name " + names[j] + 6602 " (in package " + pkg.applicationInfo.packageName + 6603 "): name already used by " 6604 + ((other != null && other.getComponentName() != null) 6605 ? other.getComponentName().getPackageName() : "?")); 6606 } 6607 } 6608 } 6609 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6610 if (r == null) { 6611 r = new StringBuilder(256); 6612 } else { 6613 r.append(' '); 6614 } 6615 r.append(p.info.name); 6616 } 6617 } 6618 if (r != null) { 6619 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 6620 } 6621 6622 N = pkg.services.size(); 6623 r = null; 6624 for (i=0; i<N; i++) { 6625 PackageParser.Service s = pkg.services.get(i); 6626 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 6627 s.info.processName, pkg.applicationInfo.uid); 6628 mServices.addService(s); 6629 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6630 if (r == null) { 6631 r = new StringBuilder(256); 6632 } else { 6633 r.append(' '); 6634 } 6635 r.append(s.info.name); 6636 } 6637 } 6638 if (r != null) { 6639 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 6640 } 6641 6642 N = pkg.receivers.size(); 6643 r = null; 6644 for (i=0; i<N; i++) { 6645 PackageParser.Activity a = pkg.receivers.get(i); 6646 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6647 a.info.processName, pkg.applicationInfo.uid); 6648 mReceivers.addActivity(a, "receiver"); 6649 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6650 if (r == null) { 6651 r = new StringBuilder(256); 6652 } else { 6653 r.append(' '); 6654 } 6655 r.append(a.info.name); 6656 } 6657 } 6658 if (r != null) { 6659 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 6660 } 6661 6662 N = pkg.activities.size(); 6663 r = null; 6664 for (i=0; i<N; i++) { 6665 PackageParser.Activity a = pkg.activities.get(i); 6666 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6667 a.info.processName, pkg.applicationInfo.uid); 6668 mActivities.addActivity(a, "activity"); 6669 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6670 if (r == null) { 6671 r = new StringBuilder(256); 6672 } else { 6673 r.append(' '); 6674 } 6675 r.append(a.info.name); 6676 } 6677 } 6678 if (r != null) { 6679 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 6680 } 6681 6682 N = pkg.permissionGroups.size(); 6683 r = null; 6684 for (i=0; i<N; i++) { 6685 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 6686 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 6687 if (cur == null) { 6688 mPermissionGroups.put(pg.info.name, pg); 6689 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6690 if (r == null) { 6691 r = new StringBuilder(256); 6692 } else { 6693 r.append(' '); 6694 } 6695 r.append(pg.info.name); 6696 } 6697 } else { 6698 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 6699 + pg.info.packageName + " ignored: original from " 6700 + cur.info.packageName); 6701 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6702 if (r == null) { 6703 r = new StringBuilder(256); 6704 } else { 6705 r.append(' '); 6706 } 6707 r.append("DUP:"); 6708 r.append(pg.info.name); 6709 } 6710 } 6711 } 6712 if (r != null) { 6713 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 6714 } 6715 6716 N = pkg.permissions.size(); 6717 r = null; 6718 for (i=0; i<N; i++) { 6719 PackageParser.Permission p = pkg.permissions.get(i); 6720 6721 // Now that permission groups have a special meaning, we ignore permission 6722 // groups for legacy apps to prevent unexpected behavior. In particular, 6723 // permissions for one app being granted to someone just becuase they happen 6724 // to be in a group defined by another app (before this had no implications). 6725 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 6726 p.group = mPermissionGroups.get(p.info.group); 6727 // Warn for a permission in an unknown group. 6728 if (p.info.group != null && p.group == null) { 6729 Slog.w(TAG, "Permission " + p.info.name + " from package " 6730 + p.info.packageName + " in an unknown group " + p.info.group); 6731 } 6732 } 6733 6734 ArrayMap<String, BasePermission> permissionMap = 6735 p.tree ? mSettings.mPermissionTrees 6736 : mSettings.mPermissions; 6737 BasePermission bp = permissionMap.get(p.info.name); 6738 6739 // Allow system apps to redefine non-system permissions 6740 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 6741 final boolean currentOwnerIsSystem = (bp.perm != null 6742 && isSystemApp(bp.perm.owner)); 6743 if (isSystemApp(p.owner)) { 6744 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 6745 // It's a built-in permission and no owner, take ownership now 6746 bp.packageSetting = pkgSetting; 6747 bp.perm = p; 6748 bp.uid = pkg.applicationInfo.uid; 6749 bp.sourcePackage = p.info.packageName; 6750 } else if (!currentOwnerIsSystem) { 6751 String msg = "New decl " + p.owner + " of permission " 6752 + p.info.name + " is system; overriding " + bp.sourcePackage; 6753 reportSettingsProblem(Log.WARN, msg); 6754 bp = null; 6755 } 6756 } 6757 } 6758 6759 if (bp == null) { 6760 bp = new BasePermission(p.info.name, p.info.packageName, 6761 BasePermission.TYPE_NORMAL); 6762 permissionMap.put(p.info.name, bp); 6763 } 6764 6765 if (bp.perm == null) { 6766 if (bp.sourcePackage == null 6767 || bp.sourcePackage.equals(p.info.packageName)) { 6768 BasePermission tree = findPermissionTreeLP(p.info.name); 6769 if (tree == null 6770 || tree.sourcePackage.equals(p.info.packageName)) { 6771 bp.packageSetting = pkgSetting; 6772 bp.perm = p; 6773 bp.uid = pkg.applicationInfo.uid; 6774 bp.sourcePackage = p.info.packageName; 6775 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6776 if (r == null) { 6777 r = new StringBuilder(256); 6778 } else { 6779 r.append(' '); 6780 } 6781 r.append(p.info.name); 6782 } 6783 } else { 6784 Slog.w(TAG, "Permission " + p.info.name + " from package " 6785 + p.info.packageName + " ignored: base tree " 6786 + tree.name + " is from package " 6787 + tree.sourcePackage); 6788 } 6789 } else { 6790 Slog.w(TAG, "Permission " + p.info.name + " from package " 6791 + p.info.packageName + " ignored: original from " 6792 + bp.sourcePackage); 6793 } 6794 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6795 if (r == null) { 6796 r = new StringBuilder(256); 6797 } else { 6798 r.append(' '); 6799 } 6800 r.append("DUP:"); 6801 r.append(p.info.name); 6802 } 6803 if (bp.perm == p) { 6804 bp.protectionLevel = p.info.protectionLevel; 6805 } 6806 } 6807 6808 if (r != null) { 6809 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 6810 } 6811 6812 N = pkg.instrumentation.size(); 6813 r = null; 6814 for (i=0; i<N; i++) { 6815 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6816 a.info.packageName = pkg.applicationInfo.packageName; 6817 a.info.sourceDir = pkg.applicationInfo.sourceDir; 6818 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 6819 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 6820 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 6821 a.info.dataDir = pkg.applicationInfo.dataDir; 6822 6823 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 6824 // need other information about the application, like the ABI and what not ? 6825 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 6826 mInstrumentation.put(a.getComponentName(), a); 6827 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6828 if (r == null) { 6829 r = new StringBuilder(256); 6830 } else { 6831 r.append(' '); 6832 } 6833 r.append(a.info.name); 6834 } 6835 } 6836 if (r != null) { 6837 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 6838 } 6839 6840 if (pkg.protectedBroadcasts != null) { 6841 N = pkg.protectedBroadcasts.size(); 6842 for (i=0; i<N; i++) { 6843 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 6844 } 6845 } 6846 6847 pkgSetting.setTimeStamp(scanFileTime); 6848 6849 // Create idmap files for pairs of (packages, overlay packages). 6850 // Note: "android", ie framework-res.apk, is handled by native layers. 6851 if (pkg.mOverlayTarget != null) { 6852 // This is an overlay package. 6853 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 6854 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 6855 mOverlays.put(pkg.mOverlayTarget, 6856 new ArrayMap<String, PackageParser.Package>()); 6857 } 6858 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 6859 map.put(pkg.packageName, pkg); 6860 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 6861 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 6862 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6863 "scanPackageLI failed to createIdmap"); 6864 } 6865 } 6866 } else if (mOverlays.containsKey(pkg.packageName) && 6867 !pkg.packageName.equals("android")) { 6868 // This is a regular package, with one or more known overlay packages. 6869 createIdmapsForPackageLI(pkg); 6870 } 6871 } 6872 6873 return pkg; 6874 } 6875 6876 /** 6877 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 6878 * i.e, so that all packages can be run inside a single process if required. 6879 * 6880 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 6881 * this function will either try and make the ABI for all packages in {@code packagesForUser} 6882 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 6883 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 6884 * updating a package that belongs to a shared user. 6885 * 6886 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 6887 * adds unnecessary complexity. 6888 */ 6889 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 6890 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { 6891 String requiredInstructionSet = null; 6892 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 6893 requiredInstructionSet = VMRuntime.getInstructionSet( 6894 scannedPackage.applicationInfo.primaryCpuAbi); 6895 } 6896 6897 PackageSetting requirer = null; 6898 for (PackageSetting ps : packagesForUser) { 6899 // If packagesForUser contains scannedPackage, we skip it. This will happen 6900 // when scannedPackage is an update of an existing package. Without this check, 6901 // we will never be able to change the ABI of any package belonging to a shared 6902 // user, even if it's compatible with other packages. 6903 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6904 if (ps.primaryCpuAbiString == null) { 6905 continue; 6906 } 6907 6908 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 6909 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 6910 // We have a mismatch between instruction sets (say arm vs arm64) warn about 6911 // this but there's not much we can do. 6912 String errorMessage = "Instruction set mismatch, " 6913 + ((requirer == null) ? "[caller]" : requirer) 6914 + " requires " + requiredInstructionSet + " whereas " + ps 6915 + " requires " + instructionSet; 6916 Slog.w(TAG, errorMessage); 6917 } 6918 6919 if (requiredInstructionSet == null) { 6920 requiredInstructionSet = instructionSet; 6921 requirer = ps; 6922 } 6923 } 6924 } 6925 6926 if (requiredInstructionSet != null) { 6927 String adjustedAbi; 6928 if (requirer != null) { 6929 // requirer != null implies that either scannedPackage was null or that scannedPackage 6930 // did not require an ABI, in which case we have to adjust scannedPackage to match 6931 // the ABI of the set (which is the same as requirer's ABI) 6932 adjustedAbi = requirer.primaryCpuAbiString; 6933 if (scannedPackage != null) { 6934 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 6935 } 6936 } else { 6937 // requirer == null implies that we're updating all ABIs in the set to 6938 // match scannedPackage. 6939 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 6940 } 6941 6942 for (PackageSetting ps : packagesForUser) { 6943 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6944 if (ps.primaryCpuAbiString != null) { 6945 continue; 6946 } 6947 6948 ps.primaryCpuAbiString = adjustedAbi; 6949 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 6950 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 6951 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 6952 6953 int result = mPackageDexOptimizer.performDexOpt(ps.pkg, 6954 null /* instruction sets */, forceDexOpt, deferDexOpt, true); 6955 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6956 ps.primaryCpuAbiString = null; 6957 ps.pkg.applicationInfo.primaryCpuAbi = null; 6958 return; 6959 } else { 6960 mInstaller.rmdex(ps.codePathString, 6961 getDexCodeInstructionSet(getPreferredInstructionSet())); 6962 } 6963 } 6964 } 6965 } 6966 } 6967 } 6968 6969 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 6970 synchronized (mPackages) { 6971 mResolverReplaced = true; 6972 // Set up information for custom user intent resolution activity. 6973 mResolveActivity.applicationInfo = pkg.applicationInfo; 6974 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 6975 mResolveActivity.packageName = pkg.applicationInfo.packageName; 6976 mResolveActivity.processName = pkg.applicationInfo.packageName; 6977 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6978 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 6979 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 6980 mResolveActivity.theme = 0; 6981 mResolveActivity.exported = true; 6982 mResolveActivity.enabled = true; 6983 mResolveInfo.activityInfo = mResolveActivity; 6984 mResolveInfo.priority = 0; 6985 mResolveInfo.preferredOrder = 0; 6986 mResolveInfo.match = 0; 6987 mResolveComponentName = mCustomResolverComponentName; 6988 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 6989 mResolveComponentName); 6990 } 6991 } 6992 6993 private static String calculateBundledApkRoot(final String codePathString) { 6994 final File codePath = new File(codePathString); 6995 final File codeRoot; 6996 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 6997 codeRoot = Environment.getRootDirectory(); 6998 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 6999 codeRoot = Environment.getOemDirectory(); 7000 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 7001 codeRoot = Environment.getVendorDirectory(); 7002 } else { 7003 // Unrecognized code path; take its top real segment as the apk root: 7004 // e.g. /something/app/blah.apk => /something 7005 try { 7006 File f = codePath.getCanonicalFile(); 7007 File parent = f.getParentFile(); // non-null because codePath is a file 7008 File tmp; 7009 while ((tmp = parent.getParentFile()) != null) { 7010 f = parent; 7011 parent = tmp; 7012 } 7013 codeRoot = f; 7014 Slog.w(TAG, "Unrecognized code path " 7015 + codePath + " - using " + codeRoot); 7016 } catch (IOException e) { 7017 // Can't canonicalize the code path -- shenanigans? 7018 Slog.w(TAG, "Can't canonicalize code path " + codePath); 7019 return Environment.getRootDirectory().getPath(); 7020 } 7021 } 7022 return codeRoot.getPath(); 7023 } 7024 7025 /** 7026 * Derive and set the location of native libraries for the given package, 7027 * which varies depending on where and how the package was installed. 7028 */ 7029 private void setNativeLibraryPaths(PackageParser.Package pkg) { 7030 final ApplicationInfo info = pkg.applicationInfo; 7031 final String codePath = pkg.codePath; 7032 final File codeFile = new File(codePath); 7033 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 7034 final boolean asecApp = info.isForwardLocked() || isExternal(info); 7035 7036 info.nativeLibraryRootDir = null; 7037 info.nativeLibraryRootRequiresIsa = false; 7038 info.nativeLibraryDir = null; 7039 info.secondaryNativeLibraryDir = null; 7040 7041 if (isApkFile(codeFile)) { 7042 // Monolithic install 7043 if (bundledApp) { 7044 // If "/system/lib64/apkname" exists, assume that is the per-package 7045 // native library directory to use; otherwise use "/system/lib/apkname". 7046 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 7047 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 7048 getPrimaryInstructionSet(info)); 7049 7050 // This is a bundled system app so choose the path based on the ABI. 7051 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 7052 // is just the default path. 7053 final String apkName = deriveCodePathName(codePath); 7054 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 7055 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 7056 apkName).getAbsolutePath(); 7057 7058 if (info.secondaryCpuAbi != null) { 7059 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 7060 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 7061 secondaryLibDir, apkName).getAbsolutePath(); 7062 } 7063 } else if (asecApp) { 7064 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 7065 .getAbsolutePath(); 7066 } else { 7067 final String apkName = deriveCodePathName(codePath); 7068 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 7069 .getAbsolutePath(); 7070 } 7071 7072 info.nativeLibraryRootRequiresIsa = false; 7073 info.nativeLibraryDir = info.nativeLibraryRootDir; 7074 } else { 7075 // Cluster install 7076 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 7077 info.nativeLibraryRootRequiresIsa = true; 7078 7079 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 7080 getPrimaryInstructionSet(info)).getAbsolutePath(); 7081 7082 if (info.secondaryCpuAbi != null) { 7083 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 7084 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 7085 } 7086 } 7087 } 7088 7089 /** 7090 * Calculate the abis and roots for a bundled app. These can uniquely 7091 * be determined from the contents of the system partition, i.e whether 7092 * it contains 64 or 32 bit shared libraries etc. We do not validate any 7093 * of this information, and instead assume that the system was built 7094 * sensibly. 7095 */ 7096 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 7097 PackageSetting pkgSetting) { 7098 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 7099 7100 // If "/system/lib64/apkname" exists, assume that is the per-package 7101 // native library directory to use; otherwise use "/system/lib/apkname". 7102 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 7103 setBundledAppAbi(pkg, apkRoot, apkName); 7104 // pkgSetting might be null during rescan following uninstall of updates 7105 // to a bundled app, so accommodate that possibility. The settings in 7106 // that case will be established later from the parsed package. 7107 // 7108 // If the settings aren't null, sync them up with what we've just derived. 7109 // note that apkRoot isn't stored in the package settings. 7110 if (pkgSetting != null) { 7111 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7112 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7113 } 7114 } 7115 7116 /** 7117 * Deduces the ABI of a bundled app and sets the relevant fields on the 7118 * parsed pkg object. 7119 * 7120 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 7121 * under which system libraries are installed. 7122 * @param apkName the name of the installed package. 7123 */ 7124 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 7125 final File codeFile = new File(pkg.codePath); 7126 7127 final boolean has64BitLibs; 7128 final boolean has32BitLibs; 7129 if (isApkFile(codeFile)) { 7130 // Monolithic install 7131 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 7132 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 7133 } else { 7134 // Cluster install 7135 final File rootDir = new File(codeFile, LIB_DIR_NAME); 7136 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 7137 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 7138 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 7139 has64BitLibs = (new File(rootDir, isa)).exists(); 7140 } else { 7141 has64BitLibs = false; 7142 } 7143 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 7144 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 7145 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 7146 has32BitLibs = (new File(rootDir, isa)).exists(); 7147 } else { 7148 has32BitLibs = false; 7149 } 7150 } 7151 7152 if (has64BitLibs && !has32BitLibs) { 7153 // The package has 64 bit libs, but not 32 bit libs. Its primary 7154 // ABI should be 64 bit. We can safely assume here that the bundled 7155 // native libraries correspond to the most preferred ABI in the list. 7156 7157 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7158 pkg.applicationInfo.secondaryCpuAbi = null; 7159 } else if (has32BitLibs && !has64BitLibs) { 7160 // The package has 32 bit libs but not 64 bit libs. Its primary 7161 // ABI should be 32 bit. 7162 7163 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7164 pkg.applicationInfo.secondaryCpuAbi = null; 7165 } else if (has32BitLibs && has64BitLibs) { 7166 // The application has both 64 and 32 bit bundled libraries. We check 7167 // here that the app declares multiArch support, and warn if it doesn't. 7168 // 7169 // We will be lenient here and record both ABIs. The primary will be the 7170 // ABI that's higher on the list, i.e, a device that's configured to prefer 7171 // 64 bit apps will see a 64 bit primary ABI, 7172 7173 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 7174 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 7175 } 7176 7177 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 7178 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7179 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7180 } else { 7181 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7182 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7183 } 7184 } else { 7185 pkg.applicationInfo.primaryCpuAbi = null; 7186 pkg.applicationInfo.secondaryCpuAbi = null; 7187 } 7188 } 7189 7190 private void killApplication(String pkgName, int appId, String reason) { 7191 // Request the ActivityManager to kill the process(only for existing packages) 7192 // so that we do not end up in a confused state while the user is still using the older 7193 // version of the application while the new one gets installed. 7194 IActivityManager am = ActivityManagerNative.getDefault(); 7195 if (am != null) { 7196 try { 7197 am.killApplicationWithAppId(pkgName, appId, reason); 7198 } catch (RemoteException e) { 7199 } 7200 } 7201 } 7202 7203 void removePackageLI(PackageSetting ps, boolean chatty) { 7204 if (DEBUG_INSTALL) { 7205 if (chatty) 7206 Log.d(TAG, "Removing package " + ps.name); 7207 } 7208 7209 // writer 7210 synchronized (mPackages) { 7211 mPackages.remove(ps.name); 7212 final PackageParser.Package pkg = ps.pkg; 7213 if (pkg != null) { 7214 cleanPackageDataStructuresLILPw(pkg, chatty); 7215 } 7216 } 7217 } 7218 7219 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 7220 if (DEBUG_INSTALL) { 7221 if (chatty) 7222 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 7223 } 7224 7225 // writer 7226 synchronized (mPackages) { 7227 mPackages.remove(pkg.applicationInfo.packageName); 7228 cleanPackageDataStructuresLILPw(pkg, chatty); 7229 } 7230 } 7231 7232 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 7233 int N = pkg.providers.size(); 7234 StringBuilder r = null; 7235 int i; 7236 for (i=0; i<N; i++) { 7237 PackageParser.Provider p = pkg.providers.get(i); 7238 mProviders.removeProvider(p); 7239 if (p.info.authority == null) { 7240 7241 /* There was another ContentProvider with this authority when 7242 * this app was installed so this authority is null, 7243 * Ignore it as we don't have to unregister the provider. 7244 */ 7245 continue; 7246 } 7247 String names[] = p.info.authority.split(";"); 7248 for (int j = 0; j < names.length; j++) { 7249 if (mProvidersByAuthority.get(names[j]) == p) { 7250 mProvidersByAuthority.remove(names[j]); 7251 if (DEBUG_REMOVE) { 7252 if (chatty) 7253 Log.d(TAG, "Unregistered content provider: " + names[j] 7254 + ", className = " + p.info.name + ", isSyncable = " 7255 + p.info.isSyncable); 7256 } 7257 } 7258 } 7259 if (DEBUG_REMOVE && chatty) { 7260 if (r == null) { 7261 r = new StringBuilder(256); 7262 } else { 7263 r.append(' '); 7264 } 7265 r.append(p.info.name); 7266 } 7267 } 7268 if (r != null) { 7269 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 7270 } 7271 7272 N = pkg.services.size(); 7273 r = null; 7274 for (i=0; i<N; i++) { 7275 PackageParser.Service s = pkg.services.get(i); 7276 mServices.removeService(s); 7277 if (chatty) { 7278 if (r == null) { 7279 r = new StringBuilder(256); 7280 } else { 7281 r.append(' '); 7282 } 7283 r.append(s.info.name); 7284 } 7285 } 7286 if (r != null) { 7287 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 7288 } 7289 7290 N = pkg.receivers.size(); 7291 r = null; 7292 for (i=0; i<N; i++) { 7293 PackageParser.Activity a = pkg.receivers.get(i); 7294 mReceivers.removeActivity(a, "receiver"); 7295 if (DEBUG_REMOVE && chatty) { 7296 if (r == null) { 7297 r = new StringBuilder(256); 7298 } else { 7299 r.append(' '); 7300 } 7301 r.append(a.info.name); 7302 } 7303 } 7304 if (r != null) { 7305 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 7306 } 7307 7308 N = pkg.activities.size(); 7309 r = null; 7310 for (i=0; i<N; i++) { 7311 PackageParser.Activity a = pkg.activities.get(i); 7312 mActivities.removeActivity(a, "activity"); 7313 if (DEBUG_REMOVE && chatty) { 7314 if (r == null) { 7315 r = new StringBuilder(256); 7316 } else { 7317 r.append(' '); 7318 } 7319 r.append(a.info.name); 7320 } 7321 } 7322 if (r != null) { 7323 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 7324 } 7325 7326 N = pkg.permissions.size(); 7327 r = null; 7328 for (i=0; i<N; i++) { 7329 PackageParser.Permission p = pkg.permissions.get(i); 7330 BasePermission bp = mSettings.mPermissions.get(p.info.name); 7331 if (bp == null) { 7332 bp = mSettings.mPermissionTrees.get(p.info.name); 7333 } 7334 if (bp != null && bp.perm == p) { 7335 bp.perm = null; 7336 if (DEBUG_REMOVE && chatty) { 7337 if (r == null) { 7338 r = new StringBuilder(256); 7339 } else { 7340 r.append(' '); 7341 } 7342 r.append(p.info.name); 7343 } 7344 } 7345 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7346 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 7347 if (appOpPerms != null) { 7348 appOpPerms.remove(pkg.packageName); 7349 } 7350 } 7351 } 7352 if (r != null) { 7353 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7354 } 7355 7356 N = pkg.requestedPermissions.size(); 7357 r = null; 7358 for (i=0; i<N; i++) { 7359 String perm = pkg.requestedPermissions.get(i); 7360 BasePermission bp = mSettings.mPermissions.get(perm); 7361 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7362 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 7363 if (appOpPerms != null) { 7364 appOpPerms.remove(pkg.packageName); 7365 if (appOpPerms.isEmpty()) { 7366 mAppOpPermissionPackages.remove(perm); 7367 } 7368 } 7369 } 7370 } 7371 if (r != null) { 7372 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7373 } 7374 7375 N = pkg.instrumentation.size(); 7376 r = null; 7377 for (i=0; i<N; i++) { 7378 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 7379 mInstrumentation.remove(a.getComponentName()); 7380 if (DEBUG_REMOVE && chatty) { 7381 if (r == null) { 7382 r = new StringBuilder(256); 7383 } else { 7384 r.append(' '); 7385 } 7386 r.append(a.info.name); 7387 } 7388 } 7389 if (r != null) { 7390 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 7391 } 7392 7393 r = null; 7394 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7395 // Only system apps can hold shared libraries. 7396 if (pkg.libraryNames != null) { 7397 for (i=0; i<pkg.libraryNames.size(); i++) { 7398 String name = pkg.libraryNames.get(i); 7399 SharedLibraryEntry cur = mSharedLibraries.get(name); 7400 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 7401 mSharedLibraries.remove(name); 7402 if (DEBUG_REMOVE && chatty) { 7403 if (r == null) { 7404 r = new StringBuilder(256); 7405 } else { 7406 r.append(' '); 7407 } 7408 r.append(name); 7409 } 7410 } 7411 } 7412 } 7413 } 7414 if (r != null) { 7415 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 7416 } 7417 } 7418 7419 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 7420 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 7421 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 7422 return true; 7423 } 7424 } 7425 return false; 7426 } 7427 7428 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 7429 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 7430 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 7431 7432 private void updatePermissionsLPw(String changingPkg, 7433 PackageParser.Package pkgInfo, int flags) { 7434 // Make sure there are no dangling permission trees. 7435 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 7436 while (it.hasNext()) { 7437 final BasePermission bp = it.next(); 7438 if (bp.packageSetting == null) { 7439 // We may not yet have parsed the package, so just see if 7440 // we still know about its settings. 7441 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7442 } 7443 if (bp.packageSetting == null) { 7444 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 7445 + " from package " + bp.sourcePackage); 7446 it.remove(); 7447 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7448 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7449 Slog.i(TAG, "Removing old permission tree: " + bp.name 7450 + " from package " + bp.sourcePackage); 7451 flags |= UPDATE_PERMISSIONS_ALL; 7452 it.remove(); 7453 } 7454 } 7455 } 7456 7457 // Make sure all dynamic permissions have been assigned to a package, 7458 // and make sure there are no dangling permissions. 7459 it = mSettings.mPermissions.values().iterator(); 7460 while (it.hasNext()) { 7461 final BasePermission bp = it.next(); 7462 if (bp.type == BasePermission.TYPE_DYNAMIC) { 7463 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 7464 + bp.name + " pkg=" + bp.sourcePackage 7465 + " info=" + bp.pendingInfo); 7466 if (bp.packageSetting == null && bp.pendingInfo != null) { 7467 final BasePermission tree = findPermissionTreeLP(bp.name); 7468 if (tree != null && tree.perm != null) { 7469 bp.packageSetting = tree.packageSetting; 7470 bp.perm = new PackageParser.Permission(tree.perm.owner, 7471 new PermissionInfo(bp.pendingInfo)); 7472 bp.perm.info.packageName = tree.perm.info.packageName; 7473 bp.perm.info.name = bp.name; 7474 bp.uid = tree.uid; 7475 } 7476 } 7477 } 7478 if (bp.packageSetting == null) { 7479 // We may not yet have parsed the package, so just see if 7480 // we still know about its settings. 7481 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7482 } 7483 if (bp.packageSetting == null) { 7484 Slog.w(TAG, "Removing dangling permission: " + bp.name 7485 + " from package " + bp.sourcePackage); 7486 it.remove(); 7487 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7488 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7489 Slog.i(TAG, "Removing old permission: " + bp.name 7490 + " from package " + bp.sourcePackage); 7491 flags |= UPDATE_PERMISSIONS_ALL; 7492 it.remove(); 7493 } 7494 } 7495 } 7496 7497 // Now update the permissions for all packages, in particular 7498 // replace the granted permissions of the system packages. 7499 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 7500 for (PackageParser.Package pkg : mPackages.values()) { 7501 if (pkg != pkgInfo) { 7502 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0, 7503 changingPkg); 7504 } 7505 } 7506 } 7507 7508 if (pkgInfo != null) { 7509 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg); 7510 } 7511 } 7512 7513 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 7514 String packageOfInterest) { 7515 // IMPORTANT: There are two types of permissions: install and runtime. 7516 // Install time permissions are granted when the app is installed to 7517 // all device users and users added in the future. Runtime permissions 7518 // are granted at runtime explicitly to specific users. Normal and signature 7519 // protected permissions are install time permissions. Dangerous permissions 7520 // are install permissions if the app's target SDK is Lollipop MR1 or older, 7521 // otherwise they are runtime permissions. This function does not manage 7522 // runtime permissions except for the case an app targeting Lollipop MR1 7523 // being upgraded to target a newer SDK, in which case dangerous permissions 7524 // are transformed from install time to runtime ones. 7525 7526 final PackageSetting ps = (PackageSetting) pkg.mExtras; 7527 if (ps == null) { 7528 return; 7529 } 7530 7531 PermissionsState permissionsState = ps.getPermissionsState(); 7532 PermissionsState origPermissions = permissionsState; 7533 7534 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 7535 7536 int[] upgradeUserIds = PermissionsState.USERS_NONE; 7537 int[] changedRuntimePermissionUserIds = PermissionsState.USERS_NONE; 7538 7539 boolean changedInstallPermission = false; 7540 7541 if (replace) { 7542 ps.installPermissionsFixed = false; 7543 if (!ps.isSharedUser()) { 7544 origPermissions = new PermissionsState(permissionsState); 7545 permissionsState.reset(); 7546 } 7547 } 7548 7549 permissionsState.setGlobalGids(mGlobalGids); 7550 7551 final int N = pkg.requestedPermissions.size(); 7552 for (int i=0; i<N; i++) { 7553 final String name = pkg.requestedPermissions.get(i); 7554 final BasePermission bp = mSettings.mPermissions.get(name); 7555 7556 if (DEBUG_INSTALL) { 7557 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 7558 } 7559 7560 if (bp == null || bp.packageSetting == null) { 7561 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7562 Slog.w(TAG, "Unknown permission " + name 7563 + " in package " + pkg.packageName); 7564 } 7565 continue; 7566 } 7567 7568 final String perm = bp.name; 7569 boolean allowedSig = false; 7570 int grant = GRANT_DENIED; 7571 7572 // Keep track of app op permissions. 7573 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7574 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 7575 if (pkgs == null) { 7576 pkgs = new ArraySet<>(); 7577 mAppOpPermissionPackages.put(bp.name, pkgs); 7578 } 7579 pkgs.add(pkg.packageName); 7580 } 7581 7582 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 7583 switch (level) { 7584 case PermissionInfo.PROTECTION_NORMAL: { 7585 // For all apps normal permissions are install time ones. 7586 grant = GRANT_INSTALL; 7587 } break; 7588 7589 case PermissionInfo.PROTECTION_DANGEROUS: { 7590 if (!RUNTIME_PERMISSIONS_ENABLED 7591 || pkg.applicationInfo.targetSdkVersion 7592 <= Build.VERSION_CODES.LOLLIPOP_MR1) { 7593 // For legacy apps dangerous permissions are install time ones. 7594 grant = GRANT_INSTALL; 7595 } else if (ps.isSystem()) { 7596 final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds(); 7597 if (origPermissions.hasInstallPermission(bp.name)) { 7598 // If a system app had an install permission, then the app was 7599 // upgraded and we grant the permissions as runtime to all users. 7600 grant = GRANT_UPGRADE; 7601 upgradeUserIds = currentUserIds; 7602 } else if (!Arrays.equals(updatedUserIds, currentUserIds)) { 7603 // If users changed since the last permissions update for a 7604 // system app, we grant the permission as runtime to the new users. 7605 grant = GRANT_UPGRADE; 7606 upgradeUserIds = currentUserIds; 7607 for (int userId : updatedUserIds) { 7608 upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId); 7609 } 7610 } else { 7611 // Otherwise, we grant the permission as runtime if the app 7612 // already had it, i.e. we preserve runtime permissions. 7613 grant = GRANT_RUNTIME; 7614 } 7615 } else if (origPermissions.hasInstallPermission(bp.name)) { 7616 // For legacy apps that became modern, install becomes runtime. 7617 grant = GRANT_UPGRADE; 7618 upgradeUserIds = currentUserIds; 7619 } else if (replace) { 7620 // For upgraded modern apps keep runtime permissions unchanged. 7621 grant = GRANT_RUNTIME; 7622 } 7623 } break; 7624 7625 case PermissionInfo.PROTECTION_SIGNATURE: { 7626 // For all apps signature permissions are install time ones. 7627 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 7628 if (allowedSig) { 7629 grant = GRANT_INSTALL; 7630 } 7631 } break; 7632 } 7633 7634 if (DEBUG_INSTALL) { 7635 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 7636 } 7637 7638 if (grant != GRANT_DENIED) { 7639 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 7640 // If this is an existing, non-system package, then 7641 // we can't add any new permissions to it. 7642 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 7643 // Except... if this is a permission that was added 7644 // to the platform (note: need to only do this when 7645 // updating the platform). 7646 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 7647 grant = GRANT_DENIED; 7648 } 7649 } 7650 } 7651 7652 switch (grant) { 7653 case GRANT_INSTALL: { 7654 // Grant an install permission. 7655 if (permissionsState.grantInstallPermission(bp) != 7656 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7657 changedInstallPermission = true; 7658 } 7659 } break; 7660 7661 case GRANT_RUNTIME: { 7662 // Grant previously granted runtime permissions. 7663 for (int userId : UserManagerService.getInstance().getUserIds()) { 7664 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 7665 if (permissionsState.grantRuntimePermission(bp, userId) == 7666 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7667 // If we cannot put the permission as it was, we have to write. 7668 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7669 changedRuntimePermissionUserIds, userId); 7670 } 7671 } 7672 } 7673 } break; 7674 7675 case GRANT_UPGRADE: { 7676 // Grant runtime permissions for a previously held install permission. 7677 permissionsState.revokeInstallPermission(bp); 7678 for (int userId : upgradeUserIds) { 7679 if (permissionsState.grantRuntimePermission(bp, userId) != 7680 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7681 // If we granted the permission, we have to write. 7682 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7683 changedRuntimePermissionUserIds, userId); 7684 } 7685 } 7686 } break; 7687 7688 default: { 7689 if (packageOfInterest == null 7690 || packageOfInterest.equals(pkg.packageName)) { 7691 Slog.w(TAG, "Not granting permission " + perm 7692 + " to package " + pkg.packageName 7693 + " because it was previously installed without"); 7694 } 7695 } break; 7696 } 7697 } else { 7698 if (permissionsState.revokeInstallPermission(bp) != 7699 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7700 changedInstallPermission = true; 7701 Slog.i(TAG, "Un-granting permission " + perm 7702 + " from package " + pkg.packageName 7703 + " (protectionLevel=" + bp.protectionLevel 7704 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7705 + ")"); 7706 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 7707 // Don't print warning for app op permissions, since it is fine for them 7708 // not to be granted, there is a UI for the user to decide. 7709 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7710 Slog.w(TAG, "Not granting permission " + perm 7711 + " to package " + pkg.packageName 7712 + " (protectionLevel=" + bp.protectionLevel 7713 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7714 + ")"); 7715 } 7716 } 7717 } 7718 } 7719 7720 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 7721 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 7722 // This is the first that we have heard about this package, so the 7723 // permissions we have now selected are fixed until explicitly 7724 // changed. 7725 ps.installPermissionsFixed = true; 7726 } 7727 7728 ps.setPermissionsUpdatedForUserIds(currentUserIds); 7729 7730 // Persist the runtime permissions state for users with changes. 7731 if (RUNTIME_PERMISSIONS_ENABLED) { 7732 for (int userId : changedRuntimePermissionUserIds) { 7733 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 7734 } 7735 } 7736 } 7737 7738 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 7739 boolean allowed = false; 7740 final int NP = PackageParser.NEW_PERMISSIONS.length; 7741 for (int ip=0; ip<NP; ip++) { 7742 final PackageParser.NewPermissionInfo npi 7743 = PackageParser.NEW_PERMISSIONS[ip]; 7744 if (npi.name.equals(perm) 7745 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 7746 allowed = true; 7747 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 7748 + pkg.packageName); 7749 break; 7750 } 7751 } 7752 return allowed; 7753 } 7754 7755 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 7756 BasePermission bp, PermissionsState origPermissions) { 7757 boolean allowed; 7758 allowed = (compareSignatures( 7759 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 7760 == PackageManager.SIGNATURE_MATCH) 7761 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 7762 == PackageManager.SIGNATURE_MATCH); 7763 if (!allowed && (bp.protectionLevel 7764 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 7765 if (isSystemApp(pkg)) { 7766 // For updated system applications, a system permission 7767 // is granted only if it had been defined by the original application. 7768 if (pkg.isUpdatedSystemApp()) { 7769 final PackageSetting sysPs = mSettings 7770 .getDisabledSystemPkgLPr(pkg.packageName); 7771 if (sysPs.getPermissionsState().hasInstallPermission(perm)) { 7772 // If the original was granted this permission, we take 7773 // that grant decision as read and propagate it to the 7774 // update. 7775 if (sysPs.isPrivileged()) { 7776 allowed = true; 7777 } 7778 } else { 7779 // The system apk may have been updated with an older 7780 // version of the one on the data partition, but which 7781 // granted a new system permission that it didn't have 7782 // before. In this case we do want to allow the app to 7783 // now get the new permission if the ancestral apk is 7784 // privileged to get it. 7785 if (sysPs.pkg != null && sysPs.isPrivileged()) { 7786 for (int j=0; 7787 j<sysPs.pkg.requestedPermissions.size(); j++) { 7788 if (perm.equals( 7789 sysPs.pkg.requestedPermissions.get(j))) { 7790 allowed = true; 7791 break; 7792 } 7793 } 7794 } 7795 } 7796 } else { 7797 allowed = isPrivilegedApp(pkg); 7798 } 7799 } 7800 } 7801 if (!allowed && (bp.protectionLevel 7802 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 7803 // For development permissions, a development permission 7804 // is granted only if it was already granted. 7805 allowed = origPermissions.hasInstallPermission(perm); 7806 } 7807 return allowed; 7808 } 7809 7810 final class ActivityIntentResolver 7811 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 7812 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7813 boolean defaultOnly, int userId) { 7814 if (!sUserManager.exists(userId)) return null; 7815 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7816 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7817 } 7818 7819 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7820 int userId) { 7821 if (!sUserManager.exists(userId)) return null; 7822 mFlags = flags; 7823 return super.queryIntent(intent, resolvedType, 7824 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7825 } 7826 7827 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7828 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 7829 if (!sUserManager.exists(userId)) return null; 7830 if (packageActivities == null) { 7831 return null; 7832 } 7833 mFlags = flags; 7834 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 7835 final int N = packageActivities.size(); 7836 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 7837 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 7838 7839 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 7840 for (int i = 0; i < N; ++i) { 7841 intentFilters = packageActivities.get(i).intents; 7842 if (intentFilters != null && intentFilters.size() > 0) { 7843 PackageParser.ActivityIntentInfo[] array = 7844 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 7845 intentFilters.toArray(array); 7846 listCut.add(array); 7847 } 7848 } 7849 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7850 } 7851 7852 public final void addActivity(PackageParser.Activity a, String type) { 7853 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 7854 mActivities.put(a.getComponentName(), a); 7855 if (DEBUG_SHOW_INFO) 7856 Log.v( 7857 TAG, " " + type + " " + 7858 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 7859 if (DEBUG_SHOW_INFO) 7860 Log.v(TAG, " Class=" + a.info.name); 7861 final int NI = a.intents.size(); 7862 for (int j=0; j<NI; j++) { 7863 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7864 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 7865 intent.setPriority(0); 7866 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 7867 + a.className + " with priority > 0, forcing to 0"); 7868 } 7869 if (DEBUG_SHOW_INFO) { 7870 Log.v(TAG, " IntentFilter:"); 7871 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7872 } 7873 if (!intent.debugCheck()) { 7874 Log.w(TAG, "==> For Activity " + a.info.name); 7875 } 7876 addFilter(intent); 7877 } 7878 } 7879 7880 public final void removeActivity(PackageParser.Activity a, String type) { 7881 mActivities.remove(a.getComponentName()); 7882 if (DEBUG_SHOW_INFO) { 7883 Log.v(TAG, " " + type + " " 7884 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 7885 : a.info.name) + ":"); 7886 Log.v(TAG, " Class=" + a.info.name); 7887 } 7888 final int NI = a.intents.size(); 7889 for (int j=0; j<NI; j++) { 7890 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7891 if (DEBUG_SHOW_INFO) { 7892 Log.v(TAG, " IntentFilter:"); 7893 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7894 } 7895 removeFilter(intent); 7896 } 7897 } 7898 7899 @Override 7900 protected boolean allowFilterResult( 7901 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 7902 ActivityInfo filterAi = filter.activity.info; 7903 for (int i=dest.size()-1; i>=0; i--) { 7904 ActivityInfo destAi = dest.get(i).activityInfo; 7905 if (destAi.name == filterAi.name 7906 && destAi.packageName == filterAi.packageName) { 7907 return false; 7908 } 7909 } 7910 return true; 7911 } 7912 7913 @Override 7914 protected ActivityIntentInfo[] newArray(int size) { 7915 return new ActivityIntentInfo[size]; 7916 } 7917 7918 @Override 7919 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 7920 if (!sUserManager.exists(userId)) return true; 7921 PackageParser.Package p = filter.activity.owner; 7922 if (p != null) { 7923 PackageSetting ps = (PackageSetting)p.mExtras; 7924 if (ps != null) { 7925 // System apps are never considered stopped for purposes of 7926 // filtering, because there may be no way for the user to 7927 // actually re-launch them. 7928 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 7929 && ps.getStopped(userId); 7930 } 7931 } 7932 return false; 7933 } 7934 7935 @Override 7936 protected boolean isPackageForFilter(String packageName, 7937 PackageParser.ActivityIntentInfo info) { 7938 return packageName.equals(info.activity.owner.packageName); 7939 } 7940 7941 @Override 7942 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 7943 int match, int userId) { 7944 if (!sUserManager.exists(userId)) return null; 7945 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 7946 return null; 7947 } 7948 final PackageParser.Activity activity = info.activity; 7949 if (mSafeMode && (activity.info.applicationInfo.flags 7950 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7951 return null; 7952 } 7953 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 7954 if (ps == null) { 7955 return null; 7956 } 7957 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 7958 ps.readUserState(userId), userId); 7959 if (ai == null) { 7960 return null; 7961 } 7962 final ResolveInfo res = new ResolveInfo(); 7963 res.activityInfo = ai; 7964 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 7965 res.filter = info; 7966 } 7967 if (info != null) { 7968 res.handleAllWebDataURI = info.handleAllWebDataURI(); 7969 } 7970 res.priority = info.getPriority(); 7971 res.preferredOrder = activity.owner.mPreferredOrder; 7972 //System.out.println("Result: " + res.activityInfo.className + 7973 // " = " + res.priority); 7974 res.match = match; 7975 res.isDefault = info.hasDefault; 7976 res.labelRes = info.labelRes; 7977 res.nonLocalizedLabel = info.nonLocalizedLabel; 7978 if (userNeedsBadging(userId)) { 7979 res.noResourceId = true; 7980 } else { 7981 res.icon = info.icon; 7982 } 7983 res.system = res.activityInfo.applicationInfo.isSystemApp(); 7984 return res; 7985 } 7986 7987 @Override 7988 protected void sortResults(List<ResolveInfo> results) { 7989 Collections.sort(results, mResolvePrioritySorter); 7990 } 7991 7992 @Override 7993 protected void dumpFilter(PrintWriter out, String prefix, 7994 PackageParser.ActivityIntentInfo filter) { 7995 out.print(prefix); out.print( 7996 Integer.toHexString(System.identityHashCode(filter.activity))); 7997 out.print(' '); 7998 filter.activity.printComponentShortName(out); 7999 out.print(" filter "); 8000 out.println(Integer.toHexString(System.identityHashCode(filter))); 8001 } 8002 8003 @Override 8004 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 8005 return filter.activity; 8006 } 8007 8008 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8009 PackageParser.Activity activity = (PackageParser.Activity)label; 8010 out.print(prefix); out.print( 8011 Integer.toHexString(System.identityHashCode(activity))); 8012 out.print(' '); 8013 activity.printComponentShortName(out); 8014 if (count > 1) { 8015 out.print(" ("); out.print(count); out.print(" filters)"); 8016 } 8017 out.println(); 8018 } 8019 8020// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8021// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8022// final List<ResolveInfo> retList = Lists.newArrayList(); 8023// while (i.hasNext()) { 8024// final ResolveInfo resolveInfo = i.next(); 8025// if (isEnabledLP(resolveInfo.activityInfo)) { 8026// retList.add(resolveInfo); 8027// } 8028// } 8029// return retList; 8030// } 8031 8032 // Keys are String (activity class name), values are Activity. 8033 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 8034 = new ArrayMap<ComponentName, PackageParser.Activity>(); 8035 private int mFlags; 8036 } 8037 8038 private final class ServiceIntentResolver 8039 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 8040 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8041 boolean defaultOnly, int userId) { 8042 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8043 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8044 } 8045 8046 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8047 int userId) { 8048 if (!sUserManager.exists(userId)) return null; 8049 mFlags = flags; 8050 return super.queryIntent(intent, resolvedType, 8051 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8052 } 8053 8054 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8055 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 8056 if (!sUserManager.exists(userId)) return null; 8057 if (packageServices == null) { 8058 return null; 8059 } 8060 mFlags = flags; 8061 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8062 final int N = packageServices.size(); 8063 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 8064 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 8065 8066 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 8067 for (int i = 0; i < N; ++i) { 8068 intentFilters = packageServices.get(i).intents; 8069 if (intentFilters != null && intentFilters.size() > 0) { 8070 PackageParser.ServiceIntentInfo[] array = 8071 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 8072 intentFilters.toArray(array); 8073 listCut.add(array); 8074 } 8075 } 8076 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8077 } 8078 8079 public final void addService(PackageParser.Service s) { 8080 mServices.put(s.getComponentName(), s); 8081 if (DEBUG_SHOW_INFO) { 8082 Log.v(TAG, " " 8083 + (s.info.nonLocalizedLabel != null 8084 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8085 Log.v(TAG, " Class=" + s.info.name); 8086 } 8087 final int NI = s.intents.size(); 8088 int j; 8089 for (j=0; j<NI; j++) { 8090 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8091 if (DEBUG_SHOW_INFO) { 8092 Log.v(TAG, " IntentFilter:"); 8093 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8094 } 8095 if (!intent.debugCheck()) { 8096 Log.w(TAG, "==> For Service " + s.info.name); 8097 } 8098 addFilter(intent); 8099 } 8100 } 8101 8102 public final void removeService(PackageParser.Service s) { 8103 mServices.remove(s.getComponentName()); 8104 if (DEBUG_SHOW_INFO) { 8105 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 8106 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8107 Log.v(TAG, " Class=" + s.info.name); 8108 } 8109 final int NI = s.intents.size(); 8110 int j; 8111 for (j=0; j<NI; j++) { 8112 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8113 if (DEBUG_SHOW_INFO) { 8114 Log.v(TAG, " IntentFilter:"); 8115 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8116 } 8117 removeFilter(intent); 8118 } 8119 } 8120 8121 @Override 8122 protected boolean allowFilterResult( 8123 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 8124 ServiceInfo filterSi = filter.service.info; 8125 for (int i=dest.size()-1; i>=0; i--) { 8126 ServiceInfo destAi = dest.get(i).serviceInfo; 8127 if (destAi.name == filterSi.name 8128 && destAi.packageName == filterSi.packageName) { 8129 return false; 8130 } 8131 } 8132 return true; 8133 } 8134 8135 @Override 8136 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 8137 return new PackageParser.ServiceIntentInfo[size]; 8138 } 8139 8140 @Override 8141 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 8142 if (!sUserManager.exists(userId)) return true; 8143 PackageParser.Package p = filter.service.owner; 8144 if (p != null) { 8145 PackageSetting ps = (PackageSetting)p.mExtras; 8146 if (ps != null) { 8147 // System apps are never considered stopped for purposes of 8148 // filtering, because there may be no way for the user to 8149 // actually re-launch them. 8150 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8151 && ps.getStopped(userId); 8152 } 8153 } 8154 return false; 8155 } 8156 8157 @Override 8158 protected boolean isPackageForFilter(String packageName, 8159 PackageParser.ServiceIntentInfo info) { 8160 return packageName.equals(info.service.owner.packageName); 8161 } 8162 8163 @Override 8164 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 8165 int match, int userId) { 8166 if (!sUserManager.exists(userId)) return null; 8167 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 8168 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 8169 return null; 8170 } 8171 final PackageParser.Service service = info.service; 8172 if (mSafeMode && (service.info.applicationInfo.flags 8173 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8174 return null; 8175 } 8176 PackageSetting ps = (PackageSetting) service.owner.mExtras; 8177 if (ps == null) { 8178 return null; 8179 } 8180 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 8181 ps.readUserState(userId), userId); 8182 if (si == null) { 8183 return null; 8184 } 8185 final ResolveInfo res = new ResolveInfo(); 8186 res.serviceInfo = si; 8187 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 8188 res.filter = filter; 8189 } 8190 res.priority = info.getPriority(); 8191 res.preferredOrder = service.owner.mPreferredOrder; 8192 res.match = match; 8193 res.isDefault = info.hasDefault; 8194 res.labelRes = info.labelRes; 8195 res.nonLocalizedLabel = info.nonLocalizedLabel; 8196 res.icon = info.icon; 8197 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 8198 return res; 8199 } 8200 8201 @Override 8202 protected void sortResults(List<ResolveInfo> results) { 8203 Collections.sort(results, mResolvePrioritySorter); 8204 } 8205 8206 @Override 8207 protected void dumpFilter(PrintWriter out, String prefix, 8208 PackageParser.ServiceIntentInfo filter) { 8209 out.print(prefix); out.print( 8210 Integer.toHexString(System.identityHashCode(filter.service))); 8211 out.print(' '); 8212 filter.service.printComponentShortName(out); 8213 out.print(" filter "); 8214 out.println(Integer.toHexString(System.identityHashCode(filter))); 8215 } 8216 8217 @Override 8218 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 8219 return filter.service; 8220 } 8221 8222 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8223 PackageParser.Service service = (PackageParser.Service)label; 8224 out.print(prefix); out.print( 8225 Integer.toHexString(System.identityHashCode(service))); 8226 out.print(' '); 8227 service.printComponentShortName(out); 8228 if (count > 1) { 8229 out.print(" ("); out.print(count); out.print(" filters)"); 8230 } 8231 out.println(); 8232 } 8233 8234// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8235// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8236// final List<ResolveInfo> retList = Lists.newArrayList(); 8237// while (i.hasNext()) { 8238// final ResolveInfo resolveInfo = (ResolveInfo) i; 8239// if (isEnabledLP(resolveInfo.serviceInfo)) { 8240// retList.add(resolveInfo); 8241// } 8242// } 8243// return retList; 8244// } 8245 8246 // Keys are String (activity class name), values are Activity. 8247 private final ArrayMap<ComponentName, PackageParser.Service> mServices 8248 = new ArrayMap<ComponentName, PackageParser.Service>(); 8249 private int mFlags; 8250 }; 8251 8252 private final class ProviderIntentResolver 8253 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 8254 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8255 boolean defaultOnly, int userId) { 8256 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8257 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8258 } 8259 8260 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8261 int userId) { 8262 if (!sUserManager.exists(userId)) 8263 return null; 8264 mFlags = flags; 8265 return super.queryIntent(intent, resolvedType, 8266 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8267 } 8268 8269 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8270 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 8271 if (!sUserManager.exists(userId)) 8272 return null; 8273 if (packageProviders == null) { 8274 return null; 8275 } 8276 mFlags = flags; 8277 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 8278 final int N = packageProviders.size(); 8279 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 8280 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 8281 8282 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 8283 for (int i = 0; i < N; ++i) { 8284 intentFilters = packageProviders.get(i).intents; 8285 if (intentFilters != null && intentFilters.size() > 0) { 8286 PackageParser.ProviderIntentInfo[] array = 8287 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 8288 intentFilters.toArray(array); 8289 listCut.add(array); 8290 } 8291 } 8292 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8293 } 8294 8295 public final void addProvider(PackageParser.Provider p) { 8296 if (mProviders.containsKey(p.getComponentName())) { 8297 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 8298 return; 8299 } 8300 8301 mProviders.put(p.getComponentName(), p); 8302 if (DEBUG_SHOW_INFO) { 8303 Log.v(TAG, " " 8304 + (p.info.nonLocalizedLabel != null 8305 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8306 Log.v(TAG, " Class=" + p.info.name); 8307 } 8308 final int NI = p.intents.size(); 8309 int j; 8310 for (j = 0; j < NI; j++) { 8311 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8312 if (DEBUG_SHOW_INFO) { 8313 Log.v(TAG, " IntentFilter:"); 8314 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8315 } 8316 if (!intent.debugCheck()) { 8317 Log.w(TAG, "==> For Provider " + p.info.name); 8318 } 8319 addFilter(intent); 8320 } 8321 } 8322 8323 public final void removeProvider(PackageParser.Provider p) { 8324 mProviders.remove(p.getComponentName()); 8325 if (DEBUG_SHOW_INFO) { 8326 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 8327 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8328 Log.v(TAG, " Class=" + p.info.name); 8329 } 8330 final int NI = p.intents.size(); 8331 int j; 8332 for (j = 0; j < NI; j++) { 8333 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8334 if (DEBUG_SHOW_INFO) { 8335 Log.v(TAG, " IntentFilter:"); 8336 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8337 } 8338 removeFilter(intent); 8339 } 8340 } 8341 8342 @Override 8343 protected boolean allowFilterResult( 8344 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 8345 ProviderInfo filterPi = filter.provider.info; 8346 for (int i = dest.size() - 1; i >= 0; i--) { 8347 ProviderInfo destPi = dest.get(i).providerInfo; 8348 if (destPi.name == filterPi.name 8349 && destPi.packageName == filterPi.packageName) { 8350 return false; 8351 } 8352 } 8353 return true; 8354 } 8355 8356 @Override 8357 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 8358 return new PackageParser.ProviderIntentInfo[size]; 8359 } 8360 8361 @Override 8362 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 8363 if (!sUserManager.exists(userId)) 8364 return true; 8365 PackageParser.Package p = filter.provider.owner; 8366 if (p != null) { 8367 PackageSetting ps = (PackageSetting) p.mExtras; 8368 if (ps != null) { 8369 // System apps are never considered stopped for purposes of 8370 // filtering, because there may be no way for the user to 8371 // actually re-launch them. 8372 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8373 && ps.getStopped(userId); 8374 } 8375 } 8376 return false; 8377 } 8378 8379 @Override 8380 protected boolean isPackageForFilter(String packageName, 8381 PackageParser.ProviderIntentInfo info) { 8382 return packageName.equals(info.provider.owner.packageName); 8383 } 8384 8385 @Override 8386 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 8387 int match, int userId) { 8388 if (!sUserManager.exists(userId)) 8389 return null; 8390 final PackageParser.ProviderIntentInfo info = filter; 8391 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 8392 return null; 8393 } 8394 final PackageParser.Provider provider = info.provider; 8395 if (mSafeMode && (provider.info.applicationInfo.flags 8396 & ApplicationInfo.FLAG_SYSTEM) == 0) { 8397 return null; 8398 } 8399 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 8400 if (ps == null) { 8401 return null; 8402 } 8403 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 8404 ps.readUserState(userId), userId); 8405 if (pi == null) { 8406 return null; 8407 } 8408 final ResolveInfo res = new ResolveInfo(); 8409 res.providerInfo = pi; 8410 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 8411 res.filter = filter; 8412 } 8413 res.priority = info.getPriority(); 8414 res.preferredOrder = provider.owner.mPreferredOrder; 8415 res.match = match; 8416 res.isDefault = info.hasDefault; 8417 res.labelRes = info.labelRes; 8418 res.nonLocalizedLabel = info.nonLocalizedLabel; 8419 res.icon = info.icon; 8420 res.system = res.providerInfo.applicationInfo.isSystemApp(); 8421 return res; 8422 } 8423 8424 @Override 8425 protected void sortResults(List<ResolveInfo> results) { 8426 Collections.sort(results, mResolvePrioritySorter); 8427 } 8428 8429 @Override 8430 protected void dumpFilter(PrintWriter out, String prefix, 8431 PackageParser.ProviderIntentInfo filter) { 8432 out.print(prefix); 8433 out.print( 8434 Integer.toHexString(System.identityHashCode(filter.provider))); 8435 out.print(' '); 8436 filter.provider.printComponentShortName(out); 8437 out.print(" filter "); 8438 out.println(Integer.toHexString(System.identityHashCode(filter))); 8439 } 8440 8441 @Override 8442 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 8443 return filter.provider; 8444 } 8445 8446 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8447 PackageParser.Provider provider = (PackageParser.Provider)label; 8448 out.print(prefix); out.print( 8449 Integer.toHexString(System.identityHashCode(provider))); 8450 out.print(' '); 8451 provider.printComponentShortName(out); 8452 if (count > 1) { 8453 out.print(" ("); out.print(count); out.print(" filters)"); 8454 } 8455 out.println(); 8456 } 8457 8458 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 8459 = new ArrayMap<ComponentName, PackageParser.Provider>(); 8460 private int mFlags; 8461 }; 8462 8463 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 8464 new Comparator<ResolveInfo>() { 8465 public int compare(ResolveInfo r1, ResolveInfo r2) { 8466 int v1 = r1.priority; 8467 int v2 = r2.priority; 8468 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 8469 if (v1 != v2) { 8470 return (v1 > v2) ? -1 : 1; 8471 } 8472 v1 = r1.preferredOrder; 8473 v2 = r2.preferredOrder; 8474 if (v1 != v2) { 8475 return (v1 > v2) ? -1 : 1; 8476 } 8477 if (r1.isDefault != r2.isDefault) { 8478 return r1.isDefault ? -1 : 1; 8479 } 8480 v1 = r1.match; 8481 v2 = r2.match; 8482 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 8483 if (v1 != v2) { 8484 return (v1 > v2) ? -1 : 1; 8485 } 8486 if (r1.system != r2.system) { 8487 return r1.system ? -1 : 1; 8488 } 8489 return 0; 8490 } 8491 }; 8492 8493 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 8494 new Comparator<ProviderInfo>() { 8495 public int compare(ProviderInfo p1, ProviderInfo p2) { 8496 final int v1 = p1.initOrder; 8497 final int v2 = p2.initOrder; 8498 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 8499 } 8500 }; 8501 8502 static final void sendPackageBroadcast(String action, String pkg, 8503 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, 8504 int[] userIds) { 8505 IActivityManager am = ActivityManagerNative.getDefault(); 8506 if (am != null) { 8507 try { 8508 if (userIds == null) { 8509 userIds = am.getRunningUserIds(); 8510 } 8511 for (int id : userIds) { 8512 final Intent intent = new Intent(action, 8513 pkg != null ? Uri.fromParts("package", pkg, null) : null); 8514 if (extras != null) { 8515 intent.putExtras(extras); 8516 } 8517 if (targetPkg != null) { 8518 intent.setPackage(targetPkg); 8519 } 8520 // Modify the UID when posting to other users 8521 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 8522 if (uid > 0 && UserHandle.getUserId(uid) != id) { 8523 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 8524 intent.putExtra(Intent.EXTRA_UID, uid); 8525 } 8526 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 8527 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 8528 if (DEBUG_BROADCASTS) { 8529 RuntimeException here = new RuntimeException("here"); 8530 here.fillInStackTrace(); 8531 Slog.d(TAG, "Sending to user " + id + ": " 8532 + intent.toShortString(false, true, false, false) 8533 + " " + intent.getExtras(), here); 8534 } 8535 am.broadcastIntent(null, intent, null, finishedReceiver, 8536 0, null, null, null, android.app.AppOpsManager.OP_NONE, 8537 finishedReceiver != null, false, id); 8538 } 8539 } catch (RemoteException ex) { 8540 } 8541 } 8542 } 8543 8544 /** 8545 * Check if the external storage media is available. This is true if there 8546 * is a mounted external storage medium or if the external storage is 8547 * emulated. 8548 */ 8549 private boolean isExternalMediaAvailable() { 8550 return mMediaMounted || Environment.isExternalStorageEmulated(); 8551 } 8552 8553 @Override 8554 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 8555 // writer 8556 synchronized (mPackages) { 8557 if (!isExternalMediaAvailable()) { 8558 // If the external storage is no longer mounted at this point, 8559 // the caller may not have been able to delete all of this 8560 // packages files and can not delete any more. Bail. 8561 return null; 8562 } 8563 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 8564 if (lastPackage != null) { 8565 pkgs.remove(lastPackage); 8566 } 8567 if (pkgs.size() > 0) { 8568 return pkgs.get(0); 8569 } 8570 } 8571 return null; 8572 } 8573 8574 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 8575 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 8576 userId, andCode ? 1 : 0, packageName); 8577 if (mSystemReady) { 8578 msg.sendToTarget(); 8579 } else { 8580 if (mPostSystemReadyMessages == null) { 8581 mPostSystemReadyMessages = new ArrayList<>(); 8582 } 8583 mPostSystemReadyMessages.add(msg); 8584 } 8585 } 8586 8587 void startCleaningPackages() { 8588 // reader 8589 synchronized (mPackages) { 8590 if (!isExternalMediaAvailable()) { 8591 return; 8592 } 8593 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 8594 return; 8595 } 8596 } 8597 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 8598 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 8599 IActivityManager am = ActivityManagerNative.getDefault(); 8600 if (am != null) { 8601 try { 8602 am.startService(null, intent, null, UserHandle.USER_OWNER); 8603 } catch (RemoteException e) { 8604 } 8605 } 8606 } 8607 8608 @Override 8609 public void installPackage(String originPath, IPackageInstallObserver2 observer, 8610 int installFlags, String installerPackageName, VerificationParams verificationParams, 8611 String packageAbiOverride) { 8612 installPackageAsUser(originPath, observer, installFlags, installerPackageName, 8613 verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); 8614 } 8615 8616 @Override 8617 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 8618 int installFlags, String installerPackageName, VerificationParams verificationParams, 8619 String packageAbiOverride, int userId) { 8620 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 8621 8622 final int callingUid = Binder.getCallingUid(); 8623 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 8624 8625 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8626 try { 8627 if (observer != null) { 8628 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 8629 } 8630 } catch (RemoteException re) { 8631 } 8632 return; 8633 } 8634 8635 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 8636 installFlags |= PackageManager.INSTALL_FROM_ADB; 8637 8638 } else { 8639 // Caller holds INSTALL_PACKAGES permission, so we're less strict 8640 // about installerPackageName. 8641 8642 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 8643 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 8644 } 8645 8646 UserHandle user; 8647 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 8648 user = UserHandle.ALL; 8649 } else { 8650 user = new UserHandle(userId); 8651 } 8652 8653 // Only system components can circumvent runtime permissions when installing. 8654 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 8655 && mContext.checkCallingOrSelfPermission(Manifest.permission 8656 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 8657 throw new SecurityException("You need the " 8658 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 8659 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 8660 } 8661 8662 verificationParams.setInstallerUid(callingUid); 8663 8664 final File originFile = new File(originPath); 8665 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 8666 8667 final Message msg = mHandler.obtainMessage(INIT_COPY); 8668 msg.obj = new InstallParams(origin, observer, installFlags, 8669 installerPackageName, null, verificationParams, user, packageAbiOverride); 8670 mHandler.sendMessage(msg); 8671 } 8672 8673 void installStage(String packageName, File stagedDir, String stagedCid, 8674 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, 8675 String installerPackageName, int installerUid, UserHandle user) { 8676 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 8677 params.referrerUri, installerUid, null); 8678 8679 final OriginInfo origin; 8680 if (stagedDir != null) { 8681 origin = OriginInfo.fromStagedFile(stagedDir); 8682 } else { 8683 origin = OriginInfo.fromStagedContainer(stagedCid); 8684 } 8685 8686 final Message msg = mHandler.obtainMessage(INIT_COPY); 8687 msg.obj = new InstallParams(origin, observer, params.installFlags, 8688 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride); 8689 mHandler.sendMessage(msg); 8690 } 8691 8692 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 8693 Bundle extras = new Bundle(1); 8694 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 8695 8696 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 8697 packageName, extras, null, null, new int[] {userId}); 8698 try { 8699 IActivityManager am = ActivityManagerNative.getDefault(); 8700 final boolean isSystem = 8701 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 8702 if (isSystem && am.isUserRunning(userId, false)) { 8703 // The just-installed/enabled app is bundled on the system, so presumed 8704 // to be able to run automatically without needing an explicit launch. 8705 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 8706 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 8707 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 8708 .setPackage(packageName); 8709 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 8710 android.app.AppOpsManager.OP_NONE, false, false, userId); 8711 } 8712 } catch (RemoteException e) { 8713 // shouldn't happen 8714 Slog.w(TAG, "Unable to bootstrap installed package", e); 8715 } 8716 } 8717 8718 @Override 8719 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 8720 int userId) { 8721 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8722 PackageSetting pkgSetting; 8723 final int uid = Binder.getCallingUid(); 8724 enforceCrossUserPermission(uid, userId, true, true, 8725 "setApplicationHiddenSetting for user " + userId); 8726 8727 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 8728 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 8729 return false; 8730 } 8731 8732 long callingId = Binder.clearCallingIdentity(); 8733 try { 8734 boolean sendAdded = false; 8735 boolean sendRemoved = false; 8736 // writer 8737 synchronized (mPackages) { 8738 pkgSetting = mSettings.mPackages.get(packageName); 8739 if (pkgSetting == null) { 8740 return false; 8741 } 8742 if (pkgSetting.getHidden(userId) != hidden) { 8743 pkgSetting.setHidden(hidden, userId); 8744 mSettings.writePackageRestrictionsLPr(userId); 8745 if (hidden) { 8746 sendRemoved = true; 8747 } else { 8748 sendAdded = true; 8749 } 8750 } 8751 } 8752 if (sendAdded) { 8753 sendPackageAddedForUser(packageName, pkgSetting, userId); 8754 return true; 8755 } 8756 if (sendRemoved) { 8757 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 8758 "hiding pkg"); 8759 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 8760 } 8761 } finally { 8762 Binder.restoreCallingIdentity(callingId); 8763 } 8764 return false; 8765 } 8766 8767 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 8768 int userId) { 8769 final PackageRemovedInfo info = new PackageRemovedInfo(); 8770 info.removedPackage = packageName; 8771 info.removedUsers = new int[] {userId}; 8772 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 8773 info.sendBroadcast(false, false, false); 8774 } 8775 8776 /** 8777 * Returns true if application is not found or there was an error. Otherwise it returns 8778 * the hidden state of the package for the given user. 8779 */ 8780 @Override 8781 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 8782 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8783 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 8784 false, "getApplicationHidden for user " + userId); 8785 PackageSetting pkgSetting; 8786 long callingId = Binder.clearCallingIdentity(); 8787 try { 8788 // writer 8789 synchronized (mPackages) { 8790 pkgSetting = mSettings.mPackages.get(packageName); 8791 if (pkgSetting == null) { 8792 return true; 8793 } 8794 return pkgSetting.getHidden(userId); 8795 } 8796 } finally { 8797 Binder.restoreCallingIdentity(callingId); 8798 } 8799 } 8800 8801 /** 8802 * @hide 8803 */ 8804 @Override 8805 public int installExistingPackageAsUser(String packageName, int userId) { 8806 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 8807 null); 8808 PackageSetting pkgSetting; 8809 final int uid = Binder.getCallingUid(); 8810 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 8811 + userId); 8812 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8813 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 8814 } 8815 8816 long callingId = Binder.clearCallingIdentity(); 8817 try { 8818 boolean sendAdded = false; 8819 8820 // writer 8821 synchronized (mPackages) { 8822 pkgSetting = mSettings.mPackages.get(packageName); 8823 if (pkgSetting == null) { 8824 return PackageManager.INSTALL_FAILED_INVALID_URI; 8825 } 8826 if (!pkgSetting.getInstalled(userId)) { 8827 pkgSetting.setInstalled(true, userId); 8828 pkgSetting.setHidden(false, userId); 8829 mSettings.writePackageRestrictionsLPr(userId); 8830 sendAdded = true; 8831 } 8832 } 8833 8834 if (sendAdded) { 8835 sendPackageAddedForUser(packageName, pkgSetting, userId); 8836 } 8837 } finally { 8838 Binder.restoreCallingIdentity(callingId); 8839 } 8840 8841 return PackageManager.INSTALL_SUCCEEDED; 8842 } 8843 8844 boolean isUserRestricted(int userId, String restrictionKey) { 8845 Bundle restrictions = sUserManager.getUserRestrictions(userId); 8846 if (restrictions.getBoolean(restrictionKey, false)) { 8847 Log.w(TAG, "User is restricted: " + restrictionKey); 8848 return true; 8849 } 8850 return false; 8851 } 8852 8853 @Override 8854 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 8855 mContext.enforceCallingOrSelfPermission( 8856 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8857 "Only package verification agents can verify applications"); 8858 8859 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8860 final PackageVerificationResponse response = new PackageVerificationResponse( 8861 verificationCode, Binder.getCallingUid()); 8862 msg.arg1 = id; 8863 msg.obj = response; 8864 mHandler.sendMessage(msg); 8865 } 8866 8867 @Override 8868 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 8869 long millisecondsToDelay) { 8870 mContext.enforceCallingOrSelfPermission( 8871 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8872 "Only package verification agents can extend verification timeouts"); 8873 8874 final PackageVerificationState state = mPendingVerification.get(id); 8875 final PackageVerificationResponse response = new PackageVerificationResponse( 8876 verificationCodeAtTimeout, Binder.getCallingUid()); 8877 8878 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 8879 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 8880 } 8881 if (millisecondsToDelay < 0) { 8882 millisecondsToDelay = 0; 8883 } 8884 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 8885 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 8886 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 8887 } 8888 8889 if ((state != null) && !state.timeoutExtended()) { 8890 state.extendTimeout(); 8891 8892 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8893 msg.arg1 = id; 8894 msg.obj = response; 8895 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 8896 } 8897 } 8898 8899 private void broadcastPackageVerified(int verificationId, Uri packageUri, 8900 int verificationCode, UserHandle user) { 8901 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 8902 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 8903 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 8904 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 8905 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 8906 8907 mContext.sendBroadcastAsUser(intent, user, 8908 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 8909 } 8910 8911 private ComponentName matchComponentForVerifier(String packageName, 8912 List<ResolveInfo> receivers) { 8913 ActivityInfo targetReceiver = null; 8914 8915 final int NR = receivers.size(); 8916 for (int i = 0; i < NR; i++) { 8917 final ResolveInfo info = receivers.get(i); 8918 if (info.activityInfo == null) { 8919 continue; 8920 } 8921 8922 if (packageName.equals(info.activityInfo.packageName)) { 8923 targetReceiver = info.activityInfo; 8924 break; 8925 } 8926 } 8927 8928 if (targetReceiver == null) { 8929 return null; 8930 } 8931 8932 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 8933 } 8934 8935 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 8936 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 8937 if (pkgInfo.verifiers.length == 0) { 8938 return null; 8939 } 8940 8941 final int N = pkgInfo.verifiers.length; 8942 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 8943 for (int i = 0; i < N; i++) { 8944 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 8945 8946 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 8947 receivers); 8948 if (comp == null) { 8949 continue; 8950 } 8951 8952 final int verifierUid = getUidForVerifier(verifierInfo); 8953 if (verifierUid == -1) { 8954 continue; 8955 } 8956 8957 if (DEBUG_VERIFY) { 8958 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 8959 + " with the correct signature"); 8960 } 8961 sufficientVerifiers.add(comp); 8962 verificationState.addSufficientVerifier(verifierUid); 8963 } 8964 8965 return sufficientVerifiers; 8966 } 8967 8968 private int getUidForVerifier(VerifierInfo verifierInfo) { 8969 synchronized (mPackages) { 8970 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 8971 if (pkg == null) { 8972 return -1; 8973 } else if (pkg.mSignatures.length != 1) { 8974 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8975 + " has more than one signature; ignoring"); 8976 return -1; 8977 } 8978 8979 /* 8980 * If the public key of the package's signature does not match 8981 * our expected public key, then this is a different package and 8982 * we should skip. 8983 */ 8984 8985 final byte[] expectedPublicKey; 8986 try { 8987 final Signature verifierSig = pkg.mSignatures[0]; 8988 final PublicKey publicKey = verifierSig.getPublicKey(); 8989 expectedPublicKey = publicKey.getEncoded(); 8990 } catch (CertificateException e) { 8991 return -1; 8992 } 8993 8994 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 8995 8996 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 8997 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8998 + " does not have the expected public key; ignoring"); 8999 return -1; 9000 } 9001 9002 return pkg.applicationInfo.uid; 9003 } 9004 } 9005 9006 @Override 9007 public void finishPackageInstall(int token) { 9008 enforceSystemOrRoot("Only the system is allowed to finish installs"); 9009 9010 if (DEBUG_INSTALL) { 9011 Slog.v(TAG, "BM finishing package install for " + token); 9012 } 9013 9014 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9015 mHandler.sendMessage(msg); 9016 } 9017 9018 /** 9019 * Get the verification agent timeout. 9020 * 9021 * @return verification timeout in milliseconds 9022 */ 9023 private long getVerificationTimeout() { 9024 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 9025 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 9026 DEFAULT_VERIFICATION_TIMEOUT); 9027 } 9028 9029 /** 9030 * Get the default verification agent response code. 9031 * 9032 * @return default verification response code 9033 */ 9034 private int getDefaultVerificationResponse() { 9035 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9036 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 9037 DEFAULT_VERIFICATION_RESPONSE); 9038 } 9039 9040 /** 9041 * Check whether or not package verification has been enabled. 9042 * 9043 * @return true if verification should be performed 9044 */ 9045 private boolean isVerificationEnabled(int userId, int installFlags) { 9046 if (!DEFAULT_VERIFY_ENABLE) { 9047 return false; 9048 } 9049 9050 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 9051 9052 // Check if installing from ADB 9053 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 9054 // Do not run verification in a test harness environment 9055 if (ActivityManager.isRunningInTestHarness()) { 9056 return false; 9057 } 9058 if (ensureVerifyAppsEnabled) { 9059 return true; 9060 } 9061 // Check if the developer does not want package verification for ADB installs 9062 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9063 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 9064 return false; 9065 } 9066 } 9067 9068 if (ensureVerifyAppsEnabled) { 9069 return true; 9070 } 9071 9072 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9073 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 9074 } 9075 9076 @Override 9077 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 9078 throws RemoteException { 9079 mContext.enforceCallingOrSelfPermission( 9080 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 9081 "Only intentfilter verification agents can verify applications"); 9082 9083 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 9084 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 9085 Binder.getCallingUid(), verificationCode, failedDomains); 9086 msg.arg1 = id; 9087 msg.obj = response; 9088 mHandler.sendMessage(msg); 9089 } 9090 9091 @Override 9092 public int getIntentVerificationStatus(String packageName, int userId) { 9093 synchronized (mPackages) { 9094 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 9095 } 9096 } 9097 9098 @Override 9099 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 9100 boolean result = false; 9101 synchronized (mPackages) { 9102 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 9103 } 9104 scheduleWritePackageRestrictionsLocked(userId); 9105 return result; 9106 } 9107 9108 @Override 9109 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 9110 synchronized (mPackages) { 9111 return mSettings.getIntentFilterVerificationsLPr(packageName); 9112 } 9113 } 9114 9115 @Override 9116 public List<IntentFilter> getAllIntentFilters(String packageName) { 9117 if (TextUtils.isEmpty(packageName)) { 9118 return Collections.<IntentFilter>emptyList(); 9119 } 9120 synchronized (mPackages) { 9121 PackageParser.Package pkg = mPackages.get(packageName); 9122 if (pkg == null || pkg.activities == null) { 9123 return Collections.<IntentFilter>emptyList(); 9124 } 9125 final int count = pkg.activities.size(); 9126 ArrayList<IntentFilter> result = new ArrayList<>(); 9127 for (int n=0; n<count; n++) { 9128 PackageParser.Activity activity = pkg.activities.get(n); 9129 if (activity.intents != null || activity.intents.size() > 0) { 9130 result.addAll(activity.intents); 9131 } 9132 } 9133 return result; 9134 } 9135 } 9136 9137 @Override 9138 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 9139 synchronized (mPackages) { 9140 return mSettings.setDefaultBrowserPackageNameLPr(packageName, userId); 9141 } 9142 } 9143 9144 @Override 9145 public String getDefaultBrowserPackageName(int userId) { 9146 synchronized (mPackages) { 9147 return mSettings.getDefaultBrowserPackageNameLPw(userId); 9148 } 9149 } 9150 9151 /** 9152 * Get the "allow unknown sources" setting. 9153 * 9154 * @return the current "allow unknown sources" setting 9155 */ 9156 private int getUnknownSourcesSettings() { 9157 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9158 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 9159 -1); 9160 } 9161 9162 @Override 9163 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 9164 final int uid = Binder.getCallingUid(); 9165 // writer 9166 synchronized (mPackages) { 9167 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 9168 if (targetPackageSetting == null) { 9169 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 9170 } 9171 9172 PackageSetting installerPackageSetting; 9173 if (installerPackageName != null) { 9174 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 9175 if (installerPackageSetting == null) { 9176 throw new IllegalArgumentException("Unknown installer package: " 9177 + installerPackageName); 9178 } 9179 } else { 9180 installerPackageSetting = null; 9181 } 9182 9183 Signature[] callerSignature; 9184 Object obj = mSettings.getUserIdLPr(uid); 9185 if (obj != null) { 9186 if (obj instanceof SharedUserSetting) { 9187 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 9188 } else if (obj instanceof PackageSetting) { 9189 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 9190 } else { 9191 throw new SecurityException("Bad object " + obj + " for uid " + uid); 9192 } 9193 } else { 9194 throw new SecurityException("Unknown calling uid " + uid); 9195 } 9196 9197 // Verify: can't set installerPackageName to a package that is 9198 // not signed with the same cert as the caller. 9199 if (installerPackageSetting != null) { 9200 if (compareSignatures(callerSignature, 9201 installerPackageSetting.signatures.mSignatures) 9202 != PackageManager.SIGNATURE_MATCH) { 9203 throw new SecurityException( 9204 "Caller does not have same cert as new installer package " 9205 + installerPackageName); 9206 } 9207 } 9208 9209 // Verify: if target already has an installer package, it must 9210 // be signed with the same cert as the caller. 9211 if (targetPackageSetting.installerPackageName != null) { 9212 PackageSetting setting = mSettings.mPackages.get( 9213 targetPackageSetting.installerPackageName); 9214 // If the currently set package isn't valid, then it's always 9215 // okay to change it. 9216 if (setting != null) { 9217 if (compareSignatures(callerSignature, 9218 setting.signatures.mSignatures) 9219 != PackageManager.SIGNATURE_MATCH) { 9220 throw new SecurityException( 9221 "Caller does not have same cert as old installer package " 9222 + targetPackageSetting.installerPackageName); 9223 } 9224 } 9225 } 9226 9227 // Okay! 9228 targetPackageSetting.installerPackageName = installerPackageName; 9229 scheduleWriteSettingsLocked(); 9230 } 9231 } 9232 9233 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 9234 // Queue up an async operation since the package installation may take a little while. 9235 mHandler.post(new Runnable() { 9236 public void run() { 9237 mHandler.removeCallbacks(this); 9238 // Result object to be returned 9239 PackageInstalledInfo res = new PackageInstalledInfo(); 9240 res.returnCode = currentStatus; 9241 res.uid = -1; 9242 res.pkg = null; 9243 res.removedInfo = new PackageRemovedInfo(); 9244 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 9245 args.doPreInstall(res.returnCode); 9246 synchronized (mInstallLock) { 9247 installPackageLI(args, res); 9248 } 9249 args.doPostInstall(res.returnCode, res.uid); 9250 } 9251 9252 // A restore should be performed at this point if (a) the install 9253 // succeeded, (b) the operation is not an update, and (c) the new 9254 // package has not opted out of backup participation. 9255 final boolean update = res.removedInfo.removedPackage != null; 9256 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 9257 boolean doRestore = !update 9258 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 9259 9260 // Set up the post-install work request bookkeeping. This will be used 9261 // and cleaned up by the post-install event handling regardless of whether 9262 // there's a restore pass performed. Token values are >= 1. 9263 int token; 9264 if (mNextInstallToken < 0) mNextInstallToken = 1; 9265 token = mNextInstallToken++; 9266 9267 PostInstallData data = new PostInstallData(args, res); 9268 mRunningInstalls.put(token, data); 9269 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 9270 9271 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 9272 // Pass responsibility to the Backup Manager. It will perform a 9273 // restore if appropriate, then pass responsibility back to the 9274 // Package Manager to run the post-install observer callbacks 9275 // and broadcasts. 9276 IBackupManager bm = IBackupManager.Stub.asInterface( 9277 ServiceManager.getService(Context.BACKUP_SERVICE)); 9278 if (bm != null) { 9279 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 9280 + " to BM for possible restore"); 9281 try { 9282 if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { 9283 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 9284 } else { 9285 doRestore = false; 9286 } 9287 } catch (RemoteException e) { 9288 // can't happen; the backup manager is local 9289 } catch (Exception e) { 9290 Slog.e(TAG, "Exception trying to enqueue restore", e); 9291 doRestore = false; 9292 } 9293 } else { 9294 Slog.e(TAG, "Backup Manager not found!"); 9295 doRestore = false; 9296 } 9297 } 9298 9299 if (!doRestore) { 9300 // No restore possible, or the Backup Manager was mysteriously not 9301 // available -- just fire the post-install work request directly. 9302 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 9303 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9304 mHandler.sendMessage(msg); 9305 } 9306 } 9307 }); 9308 } 9309 9310 private abstract class HandlerParams { 9311 private static final int MAX_RETRIES = 4; 9312 9313 /** 9314 * Number of times startCopy() has been attempted and had a non-fatal 9315 * error. 9316 */ 9317 private int mRetries = 0; 9318 9319 /** User handle for the user requesting the information or installation. */ 9320 private final UserHandle mUser; 9321 9322 HandlerParams(UserHandle user) { 9323 mUser = user; 9324 } 9325 9326 UserHandle getUser() { 9327 return mUser; 9328 } 9329 9330 final boolean startCopy() { 9331 boolean res; 9332 try { 9333 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 9334 9335 if (++mRetries > MAX_RETRIES) { 9336 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 9337 mHandler.sendEmptyMessage(MCS_GIVE_UP); 9338 handleServiceError(); 9339 return false; 9340 } else { 9341 handleStartCopy(); 9342 res = true; 9343 } 9344 } catch (RemoteException e) { 9345 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 9346 mHandler.sendEmptyMessage(MCS_RECONNECT); 9347 res = false; 9348 } 9349 handleReturnCode(); 9350 return res; 9351 } 9352 9353 final void serviceError() { 9354 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 9355 handleServiceError(); 9356 handleReturnCode(); 9357 } 9358 9359 abstract void handleStartCopy() throws RemoteException; 9360 abstract void handleServiceError(); 9361 abstract void handleReturnCode(); 9362 } 9363 9364 class MeasureParams extends HandlerParams { 9365 private final PackageStats mStats; 9366 private boolean mSuccess; 9367 9368 private final IPackageStatsObserver mObserver; 9369 9370 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 9371 super(new UserHandle(stats.userHandle)); 9372 mObserver = observer; 9373 mStats = stats; 9374 } 9375 9376 @Override 9377 public String toString() { 9378 return "MeasureParams{" 9379 + Integer.toHexString(System.identityHashCode(this)) 9380 + " " + mStats.packageName + "}"; 9381 } 9382 9383 @Override 9384 void handleStartCopy() throws RemoteException { 9385 synchronized (mInstallLock) { 9386 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 9387 } 9388 9389 if (mSuccess) { 9390 final boolean mounted; 9391 if (Environment.isExternalStorageEmulated()) { 9392 mounted = true; 9393 } else { 9394 final String status = Environment.getExternalStorageState(); 9395 mounted = (Environment.MEDIA_MOUNTED.equals(status) 9396 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 9397 } 9398 9399 if (mounted) { 9400 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 9401 9402 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 9403 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 9404 9405 mStats.externalDataSize = calculateDirectorySize(mContainerService, 9406 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 9407 9408 // Always subtract cache size, since it's a subdirectory 9409 mStats.externalDataSize -= mStats.externalCacheSize; 9410 9411 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 9412 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 9413 9414 mStats.externalObbSize = calculateDirectorySize(mContainerService, 9415 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 9416 } 9417 } 9418 } 9419 9420 @Override 9421 void handleReturnCode() { 9422 if (mObserver != null) { 9423 try { 9424 mObserver.onGetStatsCompleted(mStats, mSuccess); 9425 } catch (RemoteException e) { 9426 Slog.i(TAG, "Observer no longer exists."); 9427 } 9428 } 9429 } 9430 9431 @Override 9432 void handleServiceError() { 9433 Slog.e(TAG, "Could not measure application " + mStats.packageName 9434 + " external storage"); 9435 } 9436 } 9437 9438 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 9439 throws RemoteException { 9440 long result = 0; 9441 for (File path : paths) { 9442 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 9443 } 9444 return result; 9445 } 9446 9447 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 9448 for (File path : paths) { 9449 try { 9450 mcs.clearDirectory(path.getAbsolutePath()); 9451 } catch (RemoteException e) { 9452 } 9453 } 9454 } 9455 9456 static class OriginInfo { 9457 /** 9458 * Location where install is coming from, before it has been 9459 * copied/renamed into place. This could be a single monolithic APK 9460 * file, or a cluster directory. This location may be untrusted. 9461 */ 9462 final File file; 9463 final String cid; 9464 9465 /** 9466 * Flag indicating that {@link #file} or {@link #cid} has already been 9467 * staged, meaning downstream users don't need to defensively copy the 9468 * contents. 9469 */ 9470 final boolean staged; 9471 9472 /** 9473 * Flag indicating that {@link #file} or {@link #cid} is an already 9474 * installed app that is being moved. 9475 */ 9476 final boolean existing; 9477 9478 final String resolvedPath; 9479 final File resolvedFile; 9480 9481 static OriginInfo fromNothing() { 9482 return new OriginInfo(null, null, false, false); 9483 } 9484 9485 static OriginInfo fromUntrustedFile(File file) { 9486 return new OriginInfo(file, null, false, false); 9487 } 9488 9489 static OriginInfo fromExistingFile(File file) { 9490 return new OriginInfo(file, null, false, true); 9491 } 9492 9493 static OriginInfo fromStagedFile(File file) { 9494 return new OriginInfo(file, null, true, false); 9495 } 9496 9497 static OriginInfo fromStagedContainer(String cid) { 9498 return new OriginInfo(null, cid, true, false); 9499 } 9500 9501 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 9502 this.file = file; 9503 this.cid = cid; 9504 this.staged = staged; 9505 this.existing = existing; 9506 9507 if (cid != null) { 9508 resolvedPath = PackageHelper.getSdDir(cid); 9509 resolvedFile = new File(resolvedPath); 9510 } else if (file != null) { 9511 resolvedPath = file.getAbsolutePath(); 9512 resolvedFile = file; 9513 } else { 9514 resolvedPath = null; 9515 resolvedFile = null; 9516 } 9517 } 9518 } 9519 9520 class InstallParams extends HandlerParams { 9521 final OriginInfo origin; 9522 final IPackageInstallObserver2 observer; 9523 int installFlags; 9524 final String installerPackageName; 9525 final String volumeUuid; 9526 final VerificationParams verificationParams; 9527 private InstallArgs mArgs; 9528 private int mRet; 9529 final String packageAbiOverride; 9530 9531 InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, 9532 String installerPackageName, String volumeUuid, 9533 VerificationParams verificationParams, UserHandle user, String packageAbiOverride) { 9534 super(user); 9535 this.origin = origin; 9536 this.observer = observer; 9537 this.installFlags = installFlags; 9538 this.installerPackageName = installerPackageName; 9539 this.volumeUuid = volumeUuid; 9540 this.verificationParams = verificationParams; 9541 this.packageAbiOverride = packageAbiOverride; 9542 } 9543 9544 @Override 9545 public String toString() { 9546 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 9547 + " file=" + origin.file + " cid=" + origin.cid + "}"; 9548 } 9549 9550 public ManifestDigest getManifestDigest() { 9551 if (verificationParams == null) { 9552 return null; 9553 } 9554 return verificationParams.getManifestDigest(); 9555 } 9556 9557 private int installLocationPolicy(PackageInfoLite pkgLite) { 9558 String packageName = pkgLite.packageName; 9559 int installLocation = pkgLite.installLocation; 9560 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9561 // reader 9562 synchronized (mPackages) { 9563 PackageParser.Package pkg = mPackages.get(packageName); 9564 if (pkg != null) { 9565 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 9566 // Check for downgrading. 9567 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 9568 try { 9569 checkDowngrade(pkg, pkgLite); 9570 } catch (PackageManagerException e) { 9571 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 9572 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 9573 } 9574 } 9575 // Check for updated system application. 9576 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9577 if (onSd) { 9578 Slog.w(TAG, "Cannot install update to system app on sdcard"); 9579 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 9580 } 9581 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9582 } else { 9583 if (onSd) { 9584 // Install flag overrides everything. 9585 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9586 } 9587 // If current upgrade specifies particular preference 9588 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 9589 // Application explicitly specified internal. 9590 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9591 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 9592 // App explictly prefers external. Let policy decide 9593 } else { 9594 // Prefer previous location 9595 if (isExternal(pkg)) { 9596 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9597 } 9598 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9599 } 9600 } 9601 } else { 9602 // Invalid install. Return error code 9603 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 9604 } 9605 } 9606 } 9607 // All the special cases have been taken care of. 9608 // Return result based on recommended install location. 9609 if (onSd) { 9610 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9611 } 9612 return pkgLite.recommendedInstallLocation; 9613 } 9614 9615 /* 9616 * Invoke remote method to get package information and install 9617 * location values. Override install location based on default 9618 * policy if needed and then create install arguments based 9619 * on the install location. 9620 */ 9621 public void handleStartCopy() throws RemoteException { 9622 int ret = PackageManager.INSTALL_SUCCEEDED; 9623 9624 // If we're already staged, we've firmly committed to an install location 9625 if (origin.staged) { 9626 if (origin.file != null) { 9627 installFlags |= PackageManager.INSTALL_INTERNAL; 9628 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9629 } else if (origin.cid != null) { 9630 installFlags |= PackageManager.INSTALL_EXTERNAL; 9631 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9632 } else { 9633 throw new IllegalStateException("Invalid stage location"); 9634 } 9635 } 9636 9637 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9638 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 9639 9640 PackageInfoLite pkgLite = null; 9641 9642 if (onInt && onSd) { 9643 // Check if both bits are set. 9644 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 9645 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9646 } else { 9647 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 9648 packageAbiOverride); 9649 9650 /* 9651 * If we have too little free space, try to free cache 9652 * before giving up. 9653 */ 9654 if (!origin.staged && pkgLite.recommendedInstallLocation 9655 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9656 // TODO: focus freeing disk space on the target device 9657 final StorageManager storage = StorageManager.from(mContext); 9658 final long lowThreshold = storage.getStorageLowBytes( 9659 Environment.getDataDirectory()); 9660 9661 final long sizeBytes = mContainerService.calculateInstalledSize( 9662 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 9663 9664 if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) { 9665 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 9666 installFlags, packageAbiOverride); 9667 } 9668 9669 /* 9670 * The cache free must have deleted the file we 9671 * downloaded to install. 9672 * 9673 * TODO: fix the "freeCache" call to not delete 9674 * the file we care about. 9675 */ 9676 if (pkgLite.recommendedInstallLocation 9677 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9678 pkgLite.recommendedInstallLocation 9679 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 9680 } 9681 } 9682 } 9683 9684 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9685 int loc = pkgLite.recommendedInstallLocation; 9686 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 9687 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9688 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 9689 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9690 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9691 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9692 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 9693 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 9694 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9695 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 9696 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 9697 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 9698 } else { 9699 // Override with defaults if needed. 9700 loc = installLocationPolicy(pkgLite); 9701 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 9702 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 9703 } else if (!onSd && !onInt) { 9704 // Override install location with flags 9705 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 9706 // Set the flag to install on external media. 9707 installFlags |= PackageManager.INSTALL_EXTERNAL; 9708 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9709 } else { 9710 // Make sure the flag for installing on external 9711 // media is unset 9712 installFlags |= PackageManager.INSTALL_INTERNAL; 9713 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9714 } 9715 } 9716 } 9717 } 9718 9719 final InstallArgs args = createInstallArgs(this); 9720 mArgs = args; 9721 9722 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9723 /* 9724 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 9725 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 9726 */ 9727 int userIdentifier = getUser().getIdentifier(); 9728 if (userIdentifier == UserHandle.USER_ALL 9729 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) { 9730 userIdentifier = UserHandle.USER_OWNER; 9731 } 9732 9733 /* 9734 * Determine if we have any installed package verifiers. If we 9735 * do, then we'll defer to them to verify the packages. 9736 */ 9737 final int requiredUid = mRequiredVerifierPackage == null ? -1 9738 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 9739 if (!origin.existing && requiredUid != -1 9740 && isVerificationEnabled(userIdentifier, installFlags)) { 9741 final Intent verification = new Intent( 9742 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 9743 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9744 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 9745 PACKAGE_MIME_TYPE); 9746 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 9747 9748 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 9749 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 9750 0 /* TODO: Which userId? */); 9751 9752 if (DEBUG_VERIFY) { 9753 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 9754 + verification.toString() + " with " + pkgLite.verifiers.length 9755 + " optional verifiers"); 9756 } 9757 9758 final int verificationId = mPendingVerificationToken++; 9759 9760 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 9761 9762 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 9763 installerPackageName); 9764 9765 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 9766 installFlags); 9767 9768 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 9769 pkgLite.packageName); 9770 9771 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 9772 pkgLite.versionCode); 9773 9774 if (verificationParams != null) { 9775 if (verificationParams.getVerificationURI() != null) { 9776 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 9777 verificationParams.getVerificationURI()); 9778 } 9779 if (verificationParams.getOriginatingURI() != null) { 9780 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 9781 verificationParams.getOriginatingURI()); 9782 } 9783 if (verificationParams.getReferrer() != null) { 9784 verification.putExtra(Intent.EXTRA_REFERRER, 9785 verificationParams.getReferrer()); 9786 } 9787 if (verificationParams.getOriginatingUid() >= 0) { 9788 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 9789 verificationParams.getOriginatingUid()); 9790 } 9791 if (verificationParams.getInstallerUid() >= 0) { 9792 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 9793 verificationParams.getInstallerUid()); 9794 } 9795 } 9796 9797 final PackageVerificationState verificationState = new PackageVerificationState( 9798 requiredUid, args); 9799 9800 mPendingVerification.append(verificationId, verificationState); 9801 9802 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 9803 receivers, verificationState); 9804 9805 /* 9806 * If any sufficient verifiers were listed in the package 9807 * manifest, attempt to ask them. 9808 */ 9809 if (sufficientVerifiers != null) { 9810 final int N = sufficientVerifiers.size(); 9811 if (N == 0) { 9812 Slog.i(TAG, "Additional verifiers required, but none installed."); 9813 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 9814 } else { 9815 for (int i = 0; i < N; i++) { 9816 final ComponentName verifierComponent = sufficientVerifiers.get(i); 9817 9818 final Intent sufficientIntent = new Intent(verification); 9819 sufficientIntent.setComponent(verifierComponent); 9820 9821 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 9822 } 9823 } 9824 } 9825 9826 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 9827 mRequiredVerifierPackage, receivers); 9828 if (ret == PackageManager.INSTALL_SUCCEEDED 9829 && mRequiredVerifierPackage != null) { 9830 /* 9831 * Send the intent to the required verification agent, 9832 * but only start the verification timeout after the 9833 * target BroadcastReceivers have run. 9834 */ 9835 verification.setComponent(requiredVerifierComponent); 9836 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 9837 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9838 new BroadcastReceiver() { 9839 @Override 9840 public void onReceive(Context context, Intent intent) { 9841 final Message msg = mHandler 9842 .obtainMessage(CHECK_PENDING_VERIFICATION); 9843 msg.arg1 = verificationId; 9844 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 9845 } 9846 }, null, 0, null, null); 9847 9848 /* 9849 * We don't want the copy to proceed until verification 9850 * succeeds, so null out this field. 9851 */ 9852 mArgs = null; 9853 } 9854 } else { 9855 /* 9856 * No package verification is enabled, so immediately start 9857 * the remote call to initiate copy using temporary file. 9858 */ 9859 ret = args.copyApk(mContainerService, true); 9860 } 9861 } 9862 9863 mRet = ret; 9864 } 9865 9866 @Override 9867 void handleReturnCode() { 9868 // If mArgs is null, then MCS couldn't be reached. When it 9869 // reconnects, it will try again to install. At that point, this 9870 // will succeed. 9871 if (mArgs != null) { 9872 processPendingInstall(mArgs, mRet); 9873 } 9874 } 9875 9876 @Override 9877 void handleServiceError() { 9878 mArgs = createInstallArgs(this); 9879 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 9880 } 9881 9882 public boolean isForwardLocked() { 9883 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9884 } 9885 } 9886 9887 /** 9888 * Used during creation of InstallArgs 9889 * 9890 * @param installFlags package installation flags 9891 * @return true if should be installed on external storage 9892 */ 9893 private static boolean installOnExternalAsec(int installFlags) { 9894 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 9895 return false; 9896 } 9897 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 9898 return true; 9899 } 9900 return false; 9901 } 9902 9903 /** 9904 * Used during creation of InstallArgs 9905 * 9906 * @param installFlags package installation flags 9907 * @return true if should be installed as forward locked 9908 */ 9909 private static boolean installForwardLocked(int installFlags) { 9910 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9911 } 9912 9913 private InstallArgs createInstallArgs(InstallParams params) { 9914 if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 9915 return new AsecInstallArgs(params); 9916 } else { 9917 return new FileInstallArgs(params); 9918 } 9919 } 9920 9921 /** 9922 * Create args that describe an existing installed package. Typically used 9923 * when cleaning up old installs, or used as a move source. 9924 */ 9925 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 9926 String resourcePath, String nativeLibraryRoot, String[] instructionSets) { 9927 final boolean isInAsec; 9928 if (installOnExternalAsec(installFlags)) { 9929 /* Apps on SD card are always in ASEC containers. */ 9930 isInAsec = true; 9931 } else if (installForwardLocked(installFlags) 9932 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 9933 /* 9934 * Forward-locked apps are only in ASEC containers if they're the 9935 * new style 9936 */ 9937 isInAsec = true; 9938 } else { 9939 isInAsec = false; 9940 } 9941 9942 if (isInAsec) { 9943 return new AsecInstallArgs(codePath, instructionSets, 9944 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 9945 } else { 9946 return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot, 9947 instructionSets); 9948 } 9949 } 9950 9951 static abstract class InstallArgs { 9952 /** @see InstallParams#origin */ 9953 final OriginInfo origin; 9954 9955 final IPackageInstallObserver2 observer; 9956 // Always refers to PackageManager flags only 9957 final int installFlags; 9958 final String installerPackageName; 9959 final String volumeUuid; 9960 final ManifestDigest manifestDigest; 9961 final UserHandle user; 9962 final String abiOverride; 9963 9964 // The list of instruction sets supported by this app. This is currently 9965 // only used during the rmdex() phase to clean up resources. We can get rid of this 9966 // if we move dex files under the common app path. 9967 /* nullable */ String[] instructionSets; 9968 9969 InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, 9970 String installerPackageName, String volumeUuid, ManifestDigest manifestDigest, 9971 UserHandle user, String[] instructionSets, String abiOverride) { 9972 this.origin = origin; 9973 this.installFlags = installFlags; 9974 this.observer = observer; 9975 this.installerPackageName = installerPackageName; 9976 this.volumeUuid = volumeUuid; 9977 this.manifestDigest = manifestDigest; 9978 this.user = user; 9979 this.instructionSets = instructionSets; 9980 this.abiOverride = abiOverride; 9981 } 9982 9983 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 9984 abstract int doPreInstall(int status); 9985 9986 /** 9987 * Rename package into final resting place. All paths on the given 9988 * scanned package should be updated to reflect the rename. 9989 */ 9990 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 9991 abstract int doPostInstall(int status, int uid); 9992 9993 /** @see PackageSettingBase#codePathString */ 9994 abstract String getCodePath(); 9995 /** @see PackageSettingBase#resourcePathString */ 9996 abstract String getResourcePath(); 9997 abstract String getLegacyNativeLibraryPath(); 9998 9999 // Need installer lock especially for dex file removal. 10000 abstract void cleanUpResourcesLI(); 10001 abstract boolean doPostDeleteLI(boolean delete); 10002 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 10003 10004 /** 10005 * Called before the source arguments are copied. This is used mostly 10006 * for MoveParams when it needs to read the source file to put it in the 10007 * destination. 10008 */ 10009 int doPreCopy() { 10010 return PackageManager.INSTALL_SUCCEEDED; 10011 } 10012 10013 /** 10014 * Called after the source arguments are copied. This is used mostly for 10015 * MoveParams when it needs to read the source file to put it in the 10016 * destination. 10017 * 10018 * @return 10019 */ 10020 int doPostCopy(int uid) { 10021 return PackageManager.INSTALL_SUCCEEDED; 10022 } 10023 10024 protected boolean isFwdLocked() { 10025 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 10026 } 10027 10028 protected boolean isExternalAsec() { 10029 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10030 } 10031 10032 UserHandle getUser() { 10033 return user; 10034 } 10035 } 10036 10037 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 10038 if (!allCodePaths.isEmpty()) { 10039 if (instructionSets == null) { 10040 throw new IllegalStateException("instructionSet == null"); 10041 } 10042 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 10043 for (String codePath : allCodePaths) { 10044 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 10045 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 10046 if (retCode < 0) { 10047 Slog.w(TAG, "Couldn't remove dex file for package: " 10048 + " at location " + codePath + ", retcode=" + retCode); 10049 // we don't consider this to be a failure of the core package deletion 10050 } 10051 } 10052 } 10053 } 10054 } 10055 10056 /** 10057 * Logic to handle installation of non-ASEC applications, including copying 10058 * and renaming logic. 10059 */ 10060 class FileInstallArgs extends InstallArgs { 10061 private File codeFile; 10062 private File resourceFile; 10063 private File legacyNativeLibraryPath; 10064 10065 // Example topology: 10066 // /data/app/com.example/base.apk 10067 // /data/app/com.example/split_foo.apk 10068 // /data/app/com.example/lib/arm/libfoo.so 10069 // /data/app/com.example/lib/arm64/libfoo.so 10070 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 10071 10072 /** New install */ 10073 FileInstallArgs(InstallParams params) { 10074 super(params.origin, params.observer, params.installFlags, 10075 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10076 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10077 if (isFwdLocked()) { 10078 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 10079 } 10080 } 10081 10082 /** Existing install */ 10083 FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath, 10084 String[] instructionSets) { 10085 super(OriginInfo.fromNothing(), null, 0, null, null, null, null, instructionSets, null); 10086 this.codeFile = (codePath != null) ? new File(codePath) : null; 10087 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 10088 this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ? 10089 new File(legacyNativeLibraryPath) : null; 10090 } 10091 10092 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 10093 final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(), 10094 isFwdLocked(), abiOverride); 10095 10096 final StorageManager storage = StorageManager.from(mContext); 10097 return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory())); 10098 } 10099 10100 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10101 if (origin.staged) { 10102 Slog.d(TAG, origin.file + " already staged; skipping copy"); 10103 codeFile = origin.file; 10104 resourceFile = origin.file; 10105 return PackageManager.INSTALL_SUCCEEDED; 10106 } 10107 10108 try { 10109 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid); 10110 codeFile = tempDir; 10111 resourceFile = tempDir; 10112 } catch (IOException e) { 10113 Slog.w(TAG, "Failed to create copy file: " + e); 10114 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10115 } 10116 10117 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 10118 @Override 10119 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 10120 if (!FileUtils.isValidExtFilename(name)) { 10121 throw new IllegalArgumentException("Invalid filename: " + name); 10122 } 10123 try { 10124 final File file = new File(codeFile, name); 10125 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 10126 O_RDWR | O_CREAT, 0644); 10127 Os.chmod(file.getAbsolutePath(), 0644); 10128 return new ParcelFileDescriptor(fd); 10129 } catch (ErrnoException e) { 10130 throw new RemoteException("Failed to open: " + e.getMessage()); 10131 } 10132 } 10133 }; 10134 10135 int ret = PackageManager.INSTALL_SUCCEEDED; 10136 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 10137 if (ret != PackageManager.INSTALL_SUCCEEDED) { 10138 Slog.e(TAG, "Failed to copy package"); 10139 return ret; 10140 } 10141 10142 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 10143 NativeLibraryHelper.Handle handle = null; 10144 try { 10145 handle = NativeLibraryHelper.Handle.create(codeFile); 10146 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 10147 abiOverride); 10148 } catch (IOException e) { 10149 Slog.e(TAG, "Copying native libraries failed", e); 10150 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10151 } finally { 10152 IoUtils.closeQuietly(handle); 10153 } 10154 10155 return ret; 10156 } 10157 10158 int doPreInstall(int status) { 10159 if (status != PackageManager.INSTALL_SUCCEEDED) { 10160 cleanUp(); 10161 } 10162 return status; 10163 } 10164 10165 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10166 if (status != PackageManager.INSTALL_SUCCEEDED) { 10167 cleanUp(); 10168 return false; 10169 } else { 10170 final File targetDir = codeFile.getParentFile(); 10171 final File beforeCodeFile = codeFile; 10172 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 10173 10174 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 10175 try { 10176 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 10177 } catch (ErrnoException e) { 10178 Slog.d(TAG, "Failed to rename", e); 10179 return false; 10180 } 10181 10182 if (!SELinux.restoreconRecursive(afterCodeFile)) { 10183 Slog.d(TAG, "Failed to restorecon"); 10184 return false; 10185 } 10186 10187 // Reflect the rename internally 10188 codeFile = afterCodeFile; 10189 resourceFile = afterCodeFile; 10190 10191 // Reflect the rename in scanned details 10192 pkg.codePath = afterCodeFile.getAbsolutePath(); 10193 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10194 pkg.baseCodePath); 10195 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10196 pkg.splitCodePaths); 10197 10198 // Reflect the rename in app info 10199 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10200 pkg.applicationInfo.setCodePath(pkg.codePath); 10201 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10202 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10203 pkg.applicationInfo.setResourcePath(pkg.codePath); 10204 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10205 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10206 10207 return true; 10208 } 10209 } 10210 10211 int doPostInstall(int status, int uid) { 10212 if (status != PackageManager.INSTALL_SUCCEEDED) { 10213 cleanUp(); 10214 } 10215 return status; 10216 } 10217 10218 @Override 10219 String getCodePath() { 10220 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 10221 } 10222 10223 @Override 10224 String getResourcePath() { 10225 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 10226 } 10227 10228 @Override 10229 String getLegacyNativeLibraryPath() { 10230 return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null; 10231 } 10232 10233 private boolean cleanUp() { 10234 if (codeFile == null || !codeFile.exists()) { 10235 return false; 10236 } 10237 10238 if (codeFile.isDirectory()) { 10239 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 10240 } else { 10241 codeFile.delete(); 10242 } 10243 10244 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 10245 resourceFile.delete(); 10246 } 10247 10248 if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) { 10249 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) { 10250 Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath); 10251 } 10252 legacyNativeLibraryPath.delete(); 10253 } 10254 10255 return true; 10256 } 10257 10258 void cleanUpResourcesLI() { 10259 // Try enumerating all code paths before deleting 10260 List<String> allCodePaths = Collections.EMPTY_LIST; 10261 if (codeFile != null && codeFile.exists()) { 10262 try { 10263 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10264 allCodePaths = pkg.getAllCodePaths(); 10265 } catch (PackageParserException e) { 10266 // Ignored; we tried our best 10267 } 10268 } 10269 10270 cleanUp(); 10271 removeDexFiles(allCodePaths, instructionSets); 10272 } 10273 10274 boolean doPostDeleteLI(boolean delete) { 10275 // XXX err, shouldn't we respect the delete flag? 10276 cleanUpResourcesLI(); 10277 return true; 10278 } 10279 } 10280 10281 private boolean isAsecExternal(String cid) { 10282 final String asecPath = PackageHelper.getSdFilesystem(cid); 10283 return !asecPath.startsWith(mAsecInternalPath); 10284 } 10285 10286 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 10287 PackageManagerException { 10288 if (copyRet < 0) { 10289 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 10290 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 10291 throw new PackageManagerException(copyRet, message); 10292 } 10293 } 10294 } 10295 10296 /** 10297 * Extract the MountService "container ID" from the full code path of an 10298 * .apk. 10299 */ 10300 static String cidFromCodePath(String fullCodePath) { 10301 int eidx = fullCodePath.lastIndexOf("/"); 10302 String subStr1 = fullCodePath.substring(0, eidx); 10303 int sidx = subStr1.lastIndexOf("/"); 10304 return subStr1.substring(sidx+1, eidx); 10305 } 10306 10307 /** 10308 * Logic to handle installation of ASEC applications, including copying and 10309 * renaming logic. 10310 */ 10311 class AsecInstallArgs extends InstallArgs { 10312 static final String RES_FILE_NAME = "pkg.apk"; 10313 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 10314 10315 String cid; 10316 String packagePath; 10317 String resourcePath; 10318 String legacyNativeLibraryDir; 10319 10320 /** New install */ 10321 AsecInstallArgs(InstallParams params) { 10322 super(params.origin, params.observer, params.installFlags, 10323 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10324 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10325 } 10326 10327 /** Existing install */ 10328 AsecInstallArgs(String fullCodePath, String[] instructionSets, 10329 boolean isExternal, boolean isForwardLocked) { 10330 super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0) 10331 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10332 instructionSets, null); 10333 // Hackily pretend we're still looking at a full code path 10334 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 10335 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 10336 } 10337 10338 // Extract cid from fullCodePath 10339 int eidx = fullCodePath.lastIndexOf("/"); 10340 String subStr1 = fullCodePath.substring(0, eidx); 10341 int sidx = subStr1.lastIndexOf("/"); 10342 cid = subStr1.substring(sidx+1, eidx); 10343 setMountPath(subStr1); 10344 } 10345 10346 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 10347 super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 10348 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10349 instructionSets, null); 10350 this.cid = cid; 10351 setMountPath(PackageHelper.getSdDir(cid)); 10352 } 10353 10354 void createCopyFile() { 10355 cid = mInstallerService.allocateExternalStageCidLegacy(); 10356 } 10357 10358 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 10359 final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(), 10360 abiOverride); 10361 10362 final File target; 10363 if (isExternalAsec()) { 10364 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory(); 10365 } else { 10366 target = Environment.getDataDirectory(); 10367 } 10368 10369 final StorageManager storage = StorageManager.from(mContext); 10370 return (sizeBytes <= storage.getStorageBytesUntilLow(target)); 10371 } 10372 10373 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10374 if (origin.staged) { 10375 Slog.d(TAG, origin.cid + " already staged; skipping copy"); 10376 cid = origin.cid; 10377 setMountPath(PackageHelper.getSdDir(cid)); 10378 return PackageManager.INSTALL_SUCCEEDED; 10379 } 10380 10381 if (temp) { 10382 createCopyFile(); 10383 } else { 10384 /* 10385 * Pre-emptively destroy the container since it's destroyed if 10386 * copying fails due to it existing anyway. 10387 */ 10388 PackageHelper.destroySdDir(cid); 10389 } 10390 10391 final String newMountPath = imcs.copyPackageToContainer( 10392 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 10393 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 10394 10395 if (newMountPath != null) { 10396 setMountPath(newMountPath); 10397 return PackageManager.INSTALL_SUCCEEDED; 10398 } else { 10399 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10400 } 10401 } 10402 10403 @Override 10404 String getCodePath() { 10405 return packagePath; 10406 } 10407 10408 @Override 10409 String getResourcePath() { 10410 return resourcePath; 10411 } 10412 10413 @Override 10414 String getLegacyNativeLibraryPath() { 10415 return legacyNativeLibraryDir; 10416 } 10417 10418 int doPreInstall(int status) { 10419 if (status != PackageManager.INSTALL_SUCCEEDED) { 10420 // Destroy container 10421 PackageHelper.destroySdDir(cid); 10422 } else { 10423 boolean mounted = PackageHelper.isContainerMounted(cid); 10424 if (!mounted) { 10425 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 10426 Process.SYSTEM_UID); 10427 if (newMountPath != null) { 10428 setMountPath(newMountPath); 10429 } else { 10430 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10431 } 10432 } 10433 } 10434 return status; 10435 } 10436 10437 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10438 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 10439 String newMountPath = null; 10440 if (PackageHelper.isContainerMounted(cid)) { 10441 // Unmount the container 10442 if (!PackageHelper.unMountSdDir(cid)) { 10443 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 10444 return false; 10445 } 10446 } 10447 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10448 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 10449 " which might be stale. Will try to clean up."); 10450 // Clean up the stale container and proceed to recreate. 10451 if (!PackageHelper.destroySdDir(newCacheId)) { 10452 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 10453 return false; 10454 } 10455 // Successfully cleaned up stale container. Try to rename again. 10456 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10457 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 10458 + " inspite of cleaning it up."); 10459 return false; 10460 } 10461 } 10462 if (!PackageHelper.isContainerMounted(newCacheId)) { 10463 Slog.w(TAG, "Mounting container " + newCacheId); 10464 newMountPath = PackageHelper.mountSdDir(newCacheId, 10465 getEncryptKey(), Process.SYSTEM_UID); 10466 } else { 10467 newMountPath = PackageHelper.getSdDir(newCacheId); 10468 } 10469 if (newMountPath == null) { 10470 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 10471 return false; 10472 } 10473 Log.i(TAG, "Succesfully renamed " + cid + 10474 " to " + newCacheId + 10475 " at new path: " + newMountPath); 10476 cid = newCacheId; 10477 10478 final File beforeCodeFile = new File(packagePath); 10479 setMountPath(newMountPath); 10480 final File afterCodeFile = new File(packagePath); 10481 10482 // Reflect the rename in scanned details 10483 pkg.codePath = afterCodeFile.getAbsolutePath(); 10484 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10485 pkg.baseCodePath); 10486 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10487 pkg.splitCodePaths); 10488 10489 // Reflect the rename in app info 10490 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10491 pkg.applicationInfo.setCodePath(pkg.codePath); 10492 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10493 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10494 pkg.applicationInfo.setResourcePath(pkg.codePath); 10495 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10496 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10497 10498 return true; 10499 } 10500 10501 private void setMountPath(String mountPath) { 10502 final File mountFile = new File(mountPath); 10503 10504 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 10505 if (monolithicFile.exists()) { 10506 packagePath = monolithicFile.getAbsolutePath(); 10507 if (isFwdLocked()) { 10508 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 10509 } else { 10510 resourcePath = packagePath; 10511 } 10512 } else { 10513 packagePath = mountFile.getAbsolutePath(); 10514 resourcePath = packagePath; 10515 } 10516 10517 legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath(); 10518 } 10519 10520 int doPostInstall(int status, int uid) { 10521 if (status != PackageManager.INSTALL_SUCCEEDED) { 10522 cleanUp(); 10523 } else { 10524 final int groupOwner; 10525 final String protectedFile; 10526 if (isFwdLocked()) { 10527 groupOwner = UserHandle.getSharedAppGid(uid); 10528 protectedFile = RES_FILE_NAME; 10529 } else { 10530 groupOwner = -1; 10531 protectedFile = null; 10532 } 10533 10534 if (uid < Process.FIRST_APPLICATION_UID 10535 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 10536 Slog.e(TAG, "Failed to finalize " + cid); 10537 PackageHelper.destroySdDir(cid); 10538 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10539 } 10540 10541 boolean mounted = PackageHelper.isContainerMounted(cid); 10542 if (!mounted) { 10543 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 10544 } 10545 } 10546 return status; 10547 } 10548 10549 private void cleanUp() { 10550 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 10551 10552 // Destroy secure container 10553 PackageHelper.destroySdDir(cid); 10554 } 10555 10556 private List<String> getAllCodePaths() { 10557 final File codeFile = new File(getCodePath()); 10558 if (codeFile != null && codeFile.exists()) { 10559 try { 10560 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10561 return pkg.getAllCodePaths(); 10562 } catch (PackageParserException e) { 10563 // Ignored; we tried our best 10564 } 10565 } 10566 return Collections.EMPTY_LIST; 10567 } 10568 10569 void cleanUpResourcesLI() { 10570 // Enumerate all code paths before deleting 10571 cleanUpResourcesLI(getAllCodePaths()); 10572 } 10573 10574 private void cleanUpResourcesLI(List<String> allCodePaths) { 10575 cleanUp(); 10576 removeDexFiles(allCodePaths, instructionSets); 10577 } 10578 10579 10580 10581 String getPackageName() { 10582 return getAsecPackageName(cid); 10583 } 10584 10585 boolean doPostDeleteLI(boolean delete) { 10586 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 10587 final List<String> allCodePaths = getAllCodePaths(); 10588 boolean mounted = PackageHelper.isContainerMounted(cid); 10589 if (mounted) { 10590 // Unmount first 10591 if (PackageHelper.unMountSdDir(cid)) { 10592 mounted = false; 10593 } 10594 } 10595 if (!mounted && delete) { 10596 cleanUpResourcesLI(allCodePaths); 10597 } 10598 return !mounted; 10599 } 10600 10601 @Override 10602 int doPreCopy() { 10603 if (isFwdLocked()) { 10604 if (!PackageHelper.fixSdPermissions(cid, 10605 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 10606 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10607 } 10608 } 10609 10610 return PackageManager.INSTALL_SUCCEEDED; 10611 } 10612 10613 @Override 10614 int doPostCopy(int uid) { 10615 if (isFwdLocked()) { 10616 if (uid < Process.FIRST_APPLICATION_UID 10617 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 10618 RES_FILE_NAME)) { 10619 Slog.e(TAG, "Failed to finalize " + cid); 10620 PackageHelper.destroySdDir(cid); 10621 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10622 } 10623 } 10624 10625 return PackageManager.INSTALL_SUCCEEDED; 10626 } 10627 } 10628 10629 static String getAsecPackageName(String packageCid) { 10630 int idx = packageCid.lastIndexOf("-"); 10631 if (idx == -1) { 10632 return packageCid; 10633 } 10634 return packageCid.substring(0, idx); 10635 } 10636 10637 // Utility method used to create code paths based on package name and available index. 10638 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 10639 String idxStr = ""; 10640 int idx = 1; 10641 // Fall back to default value of idx=1 if prefix is not 10642 // part of oldCodePath 10643 if (oldCodePath != null) { 10644 String subStr = oldCodePath; 10645 // Drop the suffix right away 10646 if (suffix != null && subStr.endsWith(suffix)) { 10647 subStr = subStr.substring(0, subStr.length() - suffix.length()); 10648 } 10649 // If oldCodePath already contains prefix find out the 10650 // ending index to either increment or decrement. 10651 int sidx = subStr.lastIndexOf(prefix); 10652 if (sidx != -1) { 10653 subStr = subStr.substring(sidx + prefix.length()); 10654 if (subStr != null) { 10655 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 10656 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 10657 } 10658 try { 10659 idx = Integer.parseInt(subStr); 10660 if (idx <= 1) { 10661 idx++; 10662 } else { 10663 idx--; 10664 } 10665 } catch(NumberFormatException e) { 10666 } 10667 } 10668 } 10669 } 10670 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 10671 return prefix + idxStr; 10672 } 10673 10674 private File getNextCodePath(File targetDir, String packageName) { 10675 int suffix = 1; 10676 File result; 10677 do { 10678 result = new File(targetDir, packageName + "-" + suffix); 10679 suffix++; 10680 } while (result.exists()); 10681 return result; 10682 } 10683 10684 // Utility method that returns the relative package path with respect 10685 // to the installation directory. Like say for /data/data/com.test-1.apk 10686 // string com.test-1 is returned. 10687 static String deriveCodePathName(String codePath) { 10688 if (codePath == null) { 10689 return null; 10690 } 10691 final File codeFile = new File(codePath); 10692 final String name = codeFile.getName(); 10693 if (codeFile.isDirectory()) { 10694 return name; 10695 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 10696 final int lastDot = name.lastIndexOf('.'); 10697 return name.substring(0, lastDot); 10698 } else { 10699 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 10700 return null; 10701 } 10702 } 10703 10704 class PackageInstalledInfo { 10705 String name; 10706 int uid; 10707 // The set of users that originally had this package installed. 10708 int[] origUsers; 10709 // The set of users that now have this package installed. 10710 int[] newUsers; 10711 PackageParser.Package pkg; 10712 int returnCode; 10713 String returnMsg; 10714 PackageRemovedInfo removedInfo; 10715 10716 public void setError(int code, String msg) { 10717 returnCode = code; 10718 returnMsg = msg; 10719 Slog.w(TAG, msg); 10720 } 10721 10722 public void setError(String msg, PackageParserException e) { 10723 returnCode = e.error; 10724 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10725 Slog.w(TAG, msg, e); 10726 } 10727 10728 public void setError(String msg, PackageManagerException e) { 10729 returnCode = e.error; 10730 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10731 Slog.w(TAG, msg, e); 10732 } 10733 10734 // In some error cases we want to convey more info back to the observer 10735 String origPackage; 10736 String origPermission; 10737 } 10738 10739 /* 10740 * Install a non-existing package. 10741 */ 10742 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 10743 UserHandle user, String installerPackageName, String volumeUuid, 10744 PackageInstalledInfo res) { 10745 // Remember this for later, in case we need to rollback this install 10746 String pkgName = pkg.packageName; 10747 10748 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 10749 final boolean dataDirExists = PackageManager.getDataDirForUser(volumeUuid, pkgName, 10750 UserHandle.USER_OWNER).exists(); 10751 synchronized(mPackages) { 10752 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 10753 // A package with the same name is already installed, though 10754 // it has been renamed to an older name. The package we 10755 // are trying to install should be installed as an update to 10756 // the existing one, but that has not been requested, so bail. 10757 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10758 + " without first uninstalling package running as " 10759 + mSettings.mRenamedPackages.get(pkgName)); 10760 return; 10761 } 10762 if (mPackages.containsKey(pkgName)) { 10763 // Don't allow installation over an existing package with the same name. 10764 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10765 + " without first uninstalling."); 10766 return; 10767 } 10768 } 10769 10770 try { 10771 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 10772 System.currentTimeMillis(), user); 10773 10774 updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user); 10775 // delete the partially installed application. the data directory will have to be 10776 // restored if it was already existing 10777 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10778 // remove package from internal structures. Note that we want deletePackageX to 10779 // delete the package data and cache directories that it created in 10780 // scanPackageLocked, unless those directories existed before we even tried to 10781 // install. 10782 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 10783 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 10784 res.removedInfo, true); 10785 } 10786 10787 } catch (PackageManagerException e) { 10788 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10789 } 10790 } 10791 10792 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 10793 // Upgrade keysets are being used. Determine if new package has a superset of the 10794 // required keys. 10795 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 10796 KeySetManagerService ksms = mSettings.mKeySetManagerService; 10797 for (int i = 0; i < upgradeKeySets.length; i++) { 10798 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 10799 if (newPkg.mSigningKeys.containsAll(upgradeSet)) { 10800 return true; 10801 } 10802 } 10803 return false; 10804 } 10805 10806 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 10807 UserHandle user, String installerPackageName, String volumeUuid, 10808 PackageInstalledInfo res) { 10809 final PackageParser.Package oldPackage; 10810 final String pkgName = pkg.packageName; 10811 final int[] allUsers; 10812 final boolean[] perUserInstalled; 10813 final boolean weFroze; 10814 10815 // First find the old package info and check signatures 10816 synchronized(mPackages) { 10817 oldPackage = mPackages.get(pkgName); 10818 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 10819 final PackageSetting ps = mSettings.mPackages.get(pkgName); 10820 if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 10821 // default to original signature matching 10822 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 10823 != PackageManager.SIGNATURE_MATCH) { 10824 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10825 "New package has a different signature: " + pkgName); 10826 return; 10827 } 10828 } else { 10829 if(!checkUpgradeKeySetLP(ps, pkg)) { 10830 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10831 "New package not signed by keys specified by upgrade-keysets: " 10832 + pkgName); 10833 return; 10834 } 10835 } 10836 10837 // In case of rollback, remember per-user/profile install state 10838 allUsers = sUserManager.getUserIds(); 10839 perUserInstalled = new boolean[allUsers.length]; 10840 for (int i = 0; i < allUsers.length; i++) { 10841 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 10842 } 10843 10844 // Mark the app as frozen to prevent launching during the upgrade 10845 // process, and then kill all running instances 10846 if (!ps.frozen) { 10847 ps.frozen = true; 10848 weFroze = true; 10849 } else { 10850 weFroze = false; 10851 } 10852 } 10853 10854 // Now that we're guarded by frozen state, kill app during upgrade 10855 killApplication(pkgName, oldPackage.applicationInfo.uid, "replace pkg"); 10856 10857 try { 10858 boolean sysPkg = (isSystemApp(oldPackage)); 10859 if (sysPkg) { 10860 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10861 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 10862 } else { 10863 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10864 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 10865 } 10866 } finally { 10867 // Regardless of success or failure of upgrade steps above, always 10868 // unfreeze the package if we froze it 10869 if (weFroze) { 10870 unfreezePackage(pkgName); 10871 } 10872 } 10873 } 10874 10875 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 10876 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 10877 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 10878 String volumeUuid, PackageInstalledInfo res) { 10879 String pkgName = deletedPackage.packageName; 10880 boolean deletedPkg = true; 10881 boolean updatedSettings = false; 10882 10883 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 10884 + deletedPackage); 10885 long origUpdateTime; 10886 if (pkg.mExtras != null) { 10887 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 10888 } else { 10889 origUpdateTime = 0; 10890 } 10891 10892 // First delete the existing package while retaining the data directory 10893 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 10894 res.removedInfo, true)) { 10895 // If the existing package wasn't successfully deleted 10896 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 10897 deletedPkg = false; 10898 } else { 10899 // Successfully deleted the old package; proceed with replace. 10900 10901 // If deleted package lived in a container, give users a chance to 10902 // relinquish resources before killing. 10903 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 10904 if (DEBUG_INSTALL) { 10905 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 10906 } 10907 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 10908 final ArrayList<String> pkgList = new ArrayList<String>(1); 10909 pkgList.add(deletedPackage.applicationInfo.packageName); 10910 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 10911 } 10912 10913 deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName); 10914 try { 10915 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, 10916 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 10917 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 10918 perUserInstalled, res, user); 10919 updatedSettings = true; 10920 } catch (PackageManagerException e) { 10921 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10922 } 10923 } 10924 10925 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10926 // remove package from internal structures. Note that we want deletePackageX to 10927 // delete the package data and cache directories that it created in 10928 // scanPackageLocked, unless those directories existed before we even tried to 10929 // install. 10930 if(updatedSettings) { 10931 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 10932 deletePackageLI( 10933 pkgName, null, true, allUsers, perUserInstalled, 10934 PackageManager.DELETE_KEEP_DATA, 10935 res.removedInfo, true); 10936 } 10937 // Since we failed to install the new package we need to restore the old 10938 // package that we deleted. 10939 if (deletedPkg) { 10940 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 10941 File restoreFile = new File(deletedPackage.codePath); 10942 // Parse old package 10943 boolean oldExternal = isExternal(deletedPackage); 10944 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 10945 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 10946 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 10947 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 10948 try { 10949 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null); 10950 } catch (PackageManagerException e) { 10951 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 10952 + e.getMessage()); 10953 return; 10954 } 10955 // Restore of old package succeeded. Update permissions. 10956 // writer 10957 synchronized (mPackages) { 10958 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 10959 UPDATE_PERMISSIONS_ALL); 10960 // can downgrade to reader 10961 mSettings.writeLPr(); 10962 } 10963 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 10964 } 10965 } 10966 } 10967 10968 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 10969 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 10970 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 10971 String volumeUuid, PackageInstalledInfo res) { 10972 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 10973 + ", old=" + deletedPackage); 10974 boolean disabledSystem = false; 10975 boolean updatedSettings = false; 10976 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 10977 if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 10978 != 0) { 10979 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 10980 } 10981 String packageName = deletedPackage.packageName; 10982 if (packageName == null) { 10983 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10984 "Attempt to delete null packageName."); 10985 return; 10986 } 10987 PackageParser.Package oldPkg; 10988 PackageSetting oldPkgSetting; 10989 // reader 10990 synchronized (mPackages) { 10991 oldPkg = mPackages.get(packageName); 10992 oldPkgSetting = mSettings.mPackages.get(packageName); 10993 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 10994 (oldPkgSetting == null)) { 10995 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10996 "Couldn't find package:" + packageName + " information"); 10997 return; 10998 } 10999 } 11000 11001 res.removedInfo.uid = oldPkg.applicationInfo.uid; 11002 res.removedInfo.removedPackage = packageName; 11003 // Remove existing system package 11004 removePackageLI(oldPkgSetting, true); 11005 // writer 11006 synchronized (mPackages) { 11007 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 11008 if (!disabledSystem && deletedPackage != null) { 11009 // We didn't need to disable the .apk as a current system package, 11010 // which means we are replacing another update that is already 11011 // installed. We need to make sure to delete the older one's .apk. 11012 res.removedInfo.args = createInstallArgsForExisting(0, 11013 deletedPackage.applicationInfo.getCodePath(), 11014 deletedPackage.applicationInfo.getResourcePath(), 11015 deletedPackage.applicationInfo.nativeLibraryRootDir, 11016 getAppDexInstructionSets(deletedPackage.applicationInfo)); 11017 } else { 11018 res.removedInfo.args = null; 11019 } 11020 } 11021 11022 // Successfully disabled the old package. Now proceed with re-installation 11023 deleteCodeCacheDirsLI(pkg.volumeUuid, packageName); 11024 11025 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11026 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 11027 11028 PackageParser.Package newPackage = null; 11029 try { 11030 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user); 11031 if (newPackage.mExtras != null) { 11032 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 11033 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 11034 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 11035 11036 // is the update attempting to change shared user? that isn't going to work... 11037 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 11038 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 11039 "Forbidding shared user change from " + oldPkgSetting.sharedUser 11040 + " to " + newPkgSetting.sharedUser); 11041 updatedSettings = true; 11042 } 11043 } 11044 11045 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11046 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 11047 perUserInstalled, res, user); 11048 updatedSettings = true; 11049 } 11050 11051 } catch (PackageManagerException e) { 11052 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11053 } 11054 11055 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11056 // Re installation failed. Restore old information 11057 // Remove new pkg information 11058 if (newPackage != null) { 11059 removeInstalledPackageLI(newPackage, true); 11060 } 11061 // Add back the old system package 11062 try { 11063 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 11064 } catch (PackageManagerException e) { 11065 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 11066 } 11067 // Restore the old system information in Settings 11068 synchronized (mPackages) { 11069 if (disabledSystem) { 11070 mSettings.enableSystemPackageLPw(packageName); 11071 } 11072 if (updatedSettings) { 11073 mSettings.setInstallerPackageName(packageName, 11074 oldPkgSetting.installerPackageName); 11075 } 11076 mSettings.writeLPr(); 11077 } 11078 } 11079 } 11080 11081 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 11082 String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, 11083 UserHandle user) { 11084 String pkgName = newPackage.packageName; 11085 synchronized (mPackages) { 11086 //write settings. the installStatus will be incomplete at this stage. 11087 //note that the new package setting would have already been 11088 //added to mPackages. It hasn't been persisted yet. 11089 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 11090 mSettings.writeLPr(); 11091 } 11092 11093 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 11094 11095 synchronized (mPackages) { 11096 updatePermissionsLPw(newPackage.packageName, newPackage, 11097 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 11098 ? UPDATE_PERMISSIONS_ALL : 0)); 11099 // For system-bundled packages, we assume that installing an upgraded version 11100 // of the package implies that the user actually wants to run that new code, 11101 // so we enable the package. 11102 PackageSetting ps = mSettings.mPackages.get(pkgName); 11103 if (ps != null) { 11104 if (isSystemApp(newPackage)) { 11105 // NB: implicit assumption that system package upgrades apply to all users 11106 if (DEBUG_INSTALL) { 11107 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 11108 } 11109 if (res.origUsers != null) { 11110 for (int userHandle : res.origUsers) { 11111 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 11112 userHandle, installerPackageName); 11113 } 11114 } 11115 // Also convey the prior install/uninstall state 11116 if (allUsers != null && perUserInstalled != null) { 11117 for (int i = 0; i < allUsers.length; i++) { 11118 if (DEBUG_INSTALL) { 11119 Slog.d(TAG, " user " + allUsers[i] 11120 + " => " + perUserInstalled[i]); 11121 } 11122 ps.setInstalled(perUserInstalled[i], allUsers[i]); 11123 } 11124 // these install state changes will be persisted in the 11125 // upcoming call to mSettings.writeLPr(). 11126 } 11127 } 11128 // It's implied that when a user requests installation, they want the app to be 11129 // installed and enabled. 11130 int userId = user.getIdentifier(); 11131 if (userId != UserHandle.USER_ALL) { 11132 ps.setInstalled(true, userId); 11133 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 11134 } 11135 } 11136 res.name = pkgName; 11137 res.uid = newPackage.applicationInfo.uid; 11138 res.pkg = newPackage; 11139 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 11140 mSettings.setInstallerPackageName(pkgName, installerPackageName); 11141 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11142 //to update install status 11143 mSettings.writeLPr(); 11144 } 11145 } 11146 11147 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 11148 final int installFlags = args.installFlags; 11149 final String installerPackageName = args.installerPackageName; 11150 final String volumeUuid = args.volumeUuid; 11151 final File tmpPackageFile = new File(args.getCodePath()); 11152 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 11153 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 11154 || (args.volumeUuid != null)); 11155 boolean replace = false; 11156 int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE; 11157 // Result object to be returned 11158 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11159 11160 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 11161 // Retrieve PackageSettings and parse package 11162 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 11163 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 11164 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 11165 PackageParser pp = new PackageParser(); 11166 pp.setSeparateProcesses(mSeparateProcesses); 11167 pp.setDisplayMetrics(mMetrics); 11168 11169 final PackageParser.Package pkg; 11170 try { 11171 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 11172 } catch (PackageParserException e) { 11173 res.setError("Failed parse during installPackageLI", e); 11174 return; 11175 } 11176 11177 // Mark that we have an install time CPU ABI override. 11178 pkg.cpuAbiOverride = args.abiOverride; 11179 11180 String pkgName = res.name = pkg.packageName; 11181 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 11182 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 11183 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 11184 return; 11185 } 11186 } 11187 11188 try { 11189 pp.collectCertificates(pkg, parseFlags); 11190 pp.collectManifestDigest(pkg); 11191 } catch (PackageParserException e) { 11192 res.setError("Failed collect during installPackageLI", e); 11193 return; 11194 } 11195 11196 /* If the installer passed in a manifest digest, compare it now. */ 11197 if (args.manifestDigest != null) { 11198 if (DEBUG_INSTALL) { 11199 final String parsedManifest = pkg.manifestDigest == null ? "null" 11200 : pkg.manifestDigest.toString(); 11201 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 11202 + parsedManifest); 11203 } 11204 11205 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 11206 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 11207 return; 11208 } 11209 } else if (DEBUG_INSTALL) { 11210 final String parsedManifest = pkg.manifestDigest == null 11211 ? "null" : pkg.manifestDigest.toString(); 11212 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 11213 } 11214 11215 // Get rid of all references to package scan path via parser. 11216 pp = null; 11217 String oldCodePath = null; 11218 boolean systemApp = false; 11219 synchronized (mPackages) { 11220 // Check if installing already existing package 11221 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11222 String oldName = mSettings.mRenamedPackages.get(pkgName); 11223 if (pkg.mOriginalPackages != null 11224 && pkg.mOriginalPackages.contains(oldName) 11225 && mPackages.containsKey(oldName)) { 11226 // This package is derived from an original package, 11227 // and this device has been updating from that original 11228 // name. We must continue using the original name, so 11229 // rename the new package here. 11230 pkg.setPackageName(oldName); 11231 pkgName = pkg.packageName; 11232 replace = true; 11233 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 11234 + oldName + " pkgName=" + pkgName); 11235 } else if (mPackages.containsKey(pkgName)) { 11236 // This package, under its official name, already exists 11237 // on the device; we should replace it. 11238 replace = true; 11239 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 11240 } 11241 } 11242 11243 PackageSetting ps = mSettings.mPackages.get(pkgName); 11244 if (ps != null) { 11245 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 11246 11247 // Quick sanity check that we're signed correctly if updating; 11248 // we'll check this again later when scanning, but we want to 11249 // bail early here before tripping over redefined permissions. 11250 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 11251 try { 11252 verifySignaturesLP(ps, pkg); 11253 } catch (PackageManagerException e) { 11254 res.setError(e.error, e.getMessage()); 11255 return; 11256 } 11257 } else { 11258 if (!checkUpgradeKeySetLP(ps, pkg)) { 11259 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 11260 + pkg.packageName + " upgrade keys do not match the " 11261 + "previously installed version"); 11262 return; 11263 } 11264 } 11265 11266 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 11267 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 11268 systemApp = (ps.pkg.applicationInfo.flags & 11269 ApplicationInfo.FLAG_SYSTEM) != 0; 11270 } 11271 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11272 } 11273 11274 // Check whether the newly-scanned package wants to define an already-defined perm 11275 int N = pkg.permissions.size(); 11276 for (int i = N-1; i >= 0; i--) { 11277 PackageParser.Permission perm = pkg.permissions.get(i); 11278 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 11279 if (bp != null) { 11280 // If the defining package is signed with our cert, it's okay. This 11281 // also includes the "updating the same package" case, of course. 11282 // "updating same package" could also involve key-rotation. 11283 final boolean sigsOk; 11284 if (!bp.sourcePackage.equals(pkg.packageName) 11285 || !(bp.packageSetting instanceof PackageSetting) 11286 || !bp.packageSetting.keySetData.isUsingUpgradeKeySets() 11287 || ((PackageSetting) bp.packageSetting).sharedUser != null) { 11288 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 11289 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 11290 } else { 11291 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 11292 } 11293 if (!sigsOk) { 11294 // If the owning package is the system itself, we log but allow 11295 // install to proceed; we fail the install on all other permission 11296 // redefinitions. 11297 if (!bp.sourcePackage.equals("android")) { 11298 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 11299 + pkg.packageName + " attempting to redeclare permission " 11300 + perm.info.name + " already owned by " + bp.sourcePackage); 11301 res.origPermission = perm.info.name; 11302 res.origPackage = bp.sourcePackage; 11303 return; 11304 } else { 11305 Slog.w(TAG, "Package " + pkg.packageName 11306 + " attempting to redeclare system permission " 11307 + perm.info.name + "; ignoring new declaration"); 11308 pkg.permissions.remove(i); 11309 } 11310 } 11311 } 11312 } 11313 11314 } 11315 11316 if (systemApp && onExternal) { 11317 // Disable updates to system apps on sdcard 11318 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 11319 "Cannot install updates to system apps on sdcard"); 11320 return; 11321 } 11322 11323 // If app directory is not writable, dexopt will be called after the rename 11324 if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 11325 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 11326 scanFlags |= SCAN_NO_DEX; 11327 // Run dexopt before old package gets removed, to minimize time when app is unavailable 11328 int result = mPackageDexOptimizer 11329 .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, 11330 false /* defer */, false /* inclDependencies */); 11331 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 11332 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); 11333 return; 11334 } 11335 } 11336 11337 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 11338 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 11339 return; 11340 } 11341 11342 startIntentFilterVerifications(args.user.getIdentifier(), pkg); 11343 11344 if (replace) { 11345 replacePackageLI(pkg, parseFlags, scanFlags, args.user, 11346 installerPackageName, volumeUuid, res); 11347 } else { 11348 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 11349 args.user, installerPackageName, volumeUuid, res); 11350 } 11351 synchronized (mPackages) { 11352 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11353 if (ps != null) { 11354 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11355 } 11356 } 11357 } 11358 11359 private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) { 11360 if (mIntentFilterVerifierComponent == null) { 11361 Slog.d(TAG, "No IntentFilter verification will not be done as " 11362 + "there is no IntentFilterVerifier available!"); 11363 return; 11364 } 11365 11366 final int verifierUid = getPackageUid( 11367 mIntentFilterVerifierComponent.getPackageName(), 11368 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId); 11369 11370 mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); 11371 final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 11372 msg.obj = pkg; 11373 msg.arg1 = userId; 11374 msg.arg2 = verifierUid; 11375 11376 mHandler.sendMessage(msg); 11377 } 11378 11379 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, 11380 PackageParser.Package pkg) { 11381 int size = pkg.activities.size(); 11382 if (size == 0) { 11383 Slog.d(TAG, "No activity, so no need to verify any IntentFilter!"); 11384 return; 11385 } 11386 11387 final boolean hasDomainURLs = hasDomainURLs(pkg); 11388 if (!hasDomainURLs) { 11389 Slog.d(TAG, "No domain URLs, so no need to verify any IntentFilter!"); 11390 return; 11391 } 11392 11393 Slog.d(TAG, "Checking for userId:" + userId + " if any IntentFilter from the " + size 11394 + " Activities needs verification ..."); 11395 11396 final int verificationId = mIntentFilterVerificationToken++; 11397 int count = 0; 11398 final String packageName = pkg.packageName; 11399 ArrayList<String> allHosts = new ArrayList<>(); 11400 11401 synchronized (mPackages) { 11402 for (PackageParser.Activity a : pkg.activities) { 11403 for (ActivityIntentInfo filter : a.intents) { 11404 boolean needsFilterVerification = filter.needsVerification(); 11405 if (needsFilterVerification && needsNetworkVerificationLPr(filter)) { 11406 Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); 11407 mIntentFilterVerifier.addOneIntentFilterVerification( 11408 verifierUid, userId, verificationId, filter, packageName); 11409 count++; 11410 } else if (!needsFilterVerification) { 11411 Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString()); 11412 if (hasValidDomains(filter)) { 11413 ArrayList<String> hosts = filter.getHostsList(); 11414 if (hosts.size() > 0) { 11415 allHosts.addAll(hosts); 11416 } else { 11417 if (allHosts.isEmpty()) { 11418 allHosts.add("*"); 11419 } 11420 } 11421 } 11422 } else { 11423 Slog.d(TAG, "Verification already done for IntentFilter:" 11424 + filter.toString()); 11425 } 11426 } 11427 } 11428 } 11429 11430 if (count > 0) { 11431 mIntentFilterVerifier.startVerifications(userId); 11432 Slog.d(TAG, "Started " + count + " IntentFilter verification" 11433 + (count > 1 ? "s" : "") + " for userId:" + userId + "!"); 11434 } else { 11435 Slog.d(TAG, "No need to start any IntentFilter verification!"); 11436 if (allHosts.size() > 0 && mSettings.createIntentFilterVerificationIfNeededLPw( 11437 packageName, allHosts) != null) { 11438 scheduleWriteSettingsLocked(); 11439 } 11440 } 11441 } 11442 11443 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 11444 final ComponentName cn = filter.activity.getComponentName(); 11445 final String packageName = cn.getPackageName(); 11446 11447 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 11448 packageName); 11449 if (ivi == null) { 11450 return true; 11451 } 11452 int status = ivi.getStatus(); 11453 switch (status) { 11454 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 11455 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 11456 return true; 11457 11458 default: 11459 // Nothing to do 11460 return false; 11461 } 11462 } 11463 11464 private static boolean isMultiArch(PackageSetting ps) { 11465 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11466 } 11467 11468 private static boolean isMultiArch(ApplicationInfo info) { 11469 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11470 } 11471 11472 private static boolean isExternal(PackageParser.Package pkg) { 11473 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11474 } 11475 11476 private static boolean isExternal(PackageSetting ps) { 11477 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11478 } 11479 11480 private static boolean isExternal(ApplicationInfo info) { 11481 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11482 } 11483 11484 private static boolean isSystemApp(PackageParser.Package pkg) { 11485 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11486 } 11487 11488 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 11489 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 11490 } 11491 11492 private static boolean hasDomainURLs(PackageParser.Package pkg) { 11493 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 11494 } 11495 11496 private static boolean isSystemApp(PackageSetting ps) { 11497 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 11498 } 11499 11500 private static boolean isUpdatedSystemApp(PackageSetting ps) { 11501 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 11502 } 11503 11504 private int packageFlagsToInstallFlags(PackageSetting ps) { 11505 int installFlags = 0; 11506 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 11507 // This existing package was an external ASEC install when we have 11508 // the external flag without a UUID 11509 installFlags |= PackageManager.INSTALL_EXTERNAL; 11510 } 11511 if (ps.isForwardLocked()) { 11512 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 11513 } 11514 return installFlags; 11515 } 11516 11517 private void deleteTempPackageFiles() { 11518 final FilenameFilter filter = new FilenameFilter() { 11519 public boolean accept(File dir, String name) { 11520 return name.startsWith("vmdl") && name.endsWith(".tmp"); 11521 } 11522 }; 11523 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 11524 file.delete(); 11525 } 11526 } 11527 11528 @Override 11529 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 11530 int flags) { 11531 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 11532 flags); 11533 } 11534 11535 @Override 11536 public void deletePackage(final String packageName, 11537 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 11538 mContext.enforceCallingOrSelfPermission( 11539 android.Manifest.permission.DELETE_PACKAGES, null); 11540 final int uid = Binder.getCallingUid(); 11541 if (UserHandle.getUserId(uid) != userId) { 11542 mContext.enforceCallingPermission( 11543 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11544 "deletePackage for user " + userId); 11545 } 11546 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 11547 try { 11548 observer.onPackageDeleted(packageName, 11549 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 11550 } catch (RemoteException re) { 11551 } 11552 return; 11553 } 11554 11555 boolean uninstallBlocked = false; 11556 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 11557 int[] users = sUserManager.getUserIds(); 11558 for (int i = 0; i < users.length; ++i) { 11559 if (getBlockUninstallForUser(packageName, users[i])) { 11560 uninstallBlocked = true; 11561 break; 11562 } 11563 } 11564 } else { 11565 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 11566 } 11567 if (uninstallBlocked) { 11568 try { 11569 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 11570 null); 11571 } catch (RemoteException re) { 11572 } 11573 return; 11574 } 11575 11576 if (DEBUG_REMOVE) { 11577 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 11578 } 11579 // Queue up an async operation since the package deletion may take a little while. 11580 mHandler.post(new Runnable() { 11581 public void run() { 11582 mHandler.removeCallbacks(this); 11583 final int returnCode = deletePackageX(packageName, userId, flags); 11584 if (observer != null) { 11585 try { 11586 observer.onPackageDeleted(packageName, returnCode, null); 11587 } catch (RemoteException e) { 11588 Log.i(TAG, "Observer no longer exists."); 11589 } //end catch 11590 } //end if 11591 } //end run 11592 }); 11593 } 11594 11595 private boolean isPackageDeviceAdmin(String packageName, int userId) { 11596 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 11597 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 11598 try { 11599 if (dpm != null) { 11600 if (dpm.isDeviceOwner(packageName)) { 11601 return true; 11602 } 11603 int[] users; 11604 if (userId == UserHandle.USER_ALL) { 11605 users = sUserManager.getUserIds(); 11606 } else { 11607 users = new int[]{userId}; 11608 } 11609 for (int i = 0; i < users.length; ++i) { 11610 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 11611 return true; 11612 } 11613 } 11614 } 11615 } catch (RemoteException e) { 11616 } 11617 return false; 11618 } 11619 11620 /** 11621 * This method is an internal method that could be get invoked either 11622 * to delete an installed package or to clean up a failed installation. 11623 * After deleting an installed package, a broadcast is sent to notify any 11624 * listeners that the package has been installed. For cleaning up a failed 11625 * installation, the broadcast is not necessary since the package's 11626 * installation wouldn't have sent the initial broadcast either 11627 * The key steps in deleting a package are 11628 * deleting the package information in internal structures like mPackages, 11629 * deleting the packages base directories through installd 11630 * updating mSettings to reflect current status 11631 * persisting settings for later use 11632 * sending a broadcast if necessary 11633 */ 11634 private int deletePackageX(String packageName, int userId, int flags) { 11635 final PackageRemovedInfo info = new PackageRemovedInfo(); 11636 final boolean res; 11637 11638 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 11639 ? UserHandle.ALL : new UserHandle(userId); 11640 11641 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 11642 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 11643 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 11644 } 11645 11646 boolean removedForAllUsers = false; 11647 boolean systemUpdate = false; 11648 11649 // for the uninstall-updates case and restricted profiles, remember the per- 11650 // userhandle installed state 11651 int[] allUsers; 11652 boolean[] perUserInstalled; 11653 synchronized (mPackages) { 11654 PackageSetting ps = mSettings.mPackages.get(packageName); 11655 allUsers = sUserManager.getUserIds(); 11656 perUserInstalled = new boolean[allUsers.length]; 11657 for (int i = 0; i < allUsers.length; i++) { 11658 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 11659 } 11660 } 11661 11662 synchronized (mInstallLock) { 11663 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 11664 res = deletePackageLI(packageName, removeForUser, 11665 true, allUsers, perUserInstalled, 11666 flags | REMOVE_CHATTY, info, true); 11667 systemUpdate = info.isRemovedPackageSystemUpdate; 11668 if (res && !systemUpdate && mPackages.get(packageName) == null) { 11669 removedForAllUsers = true; 11670 } 11671 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 11672 + " removedForAllUsers=" + removedForAllUsers); 11673 } 11674 11675 if (res) { 11676 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 11677 11678 // If the removed package was a system update, the old system package 11679 // was re-enabled; we need to broadcast this information 11680 if (systemUpdate) { 11681 Bundle extras = new Bundle(1); 11682 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 11683 ? info.removedAppId : info.uid); 11684 extras.putBoolean(Intent.EXTRA_REPLACING, true); 11685 11686 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 11687 extras, null, null, null); 11688 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 11689 extras, null, null, null); 11690 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 11691 null, packageName, null, null); 11692 } 11693 } 11694 // Force a gc here. 11695 Runtime.getRuntime().gc(); 11696 // Delete the resources here after sending the broadcast to let 11697 // other processes clean up before deleting resources. 11698 if (info.args != null) { 11699 synchronized (mInstallLock) { 11700 info.args.doPostDeleteLI(true); 11701 } 11702 } 11703 11704 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 11705 } 11706 11707 static class PackageRemovedInfo { 11708 String removedPackage; 11709 int uid = -1; 11710 int removedAppId = -1; 11711 int[] removedUsers = null; 11712 boolean isRemovedPackageSystemUpdate = false; 11713 // Clean up resources deleted packages. 11714 InstallArgs args = null; 11715 11716 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 11717 Bundle extras = new Bundle(1); 11718 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 11719 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 11720 if (replacing) { 11721 extras.putBoolean(Intent.EXTRA_REPLACING, true); 11722 } 11723 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 11724 if (removedPackage != null) { 11725 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 11726 extras, null, null, removedUsers); 11727 if (fullRemove && !replacing) { 11728 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 11729 extras, null, null, removedUsers); 11730 } 11731 } 11732 if (removedAppId >= 0) { 11733 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 11734 removedUsers); 11735 } 11736 } 11737 } 11738 11739 /* 11740 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 11741 * flag is not set, the data directory is removed as well. 11742 * make sure this flag is set for partially installed apps. If not its meaningless to 11743 * delete a partially installed application. 11744 */ 11745 private void removePackageDataLI(PackageSetting ps, 11746 int[] allUserHandles, boolean[] perUserInstalled, 11747 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 11748 String packageName = ps.name; 11749 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 11750 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 11751 // Retrieve object to delete permissions for shared user later on 11752 final PackageSetting deletedPs; 11753 // reader 11754 synchronized (mPackages) { 11755 deletedPs = mSettings.mPackages.get(packageName); 11756 if (outInfo != null) { 11757 outInfo.removedPackage = packageName; 11758 outInfo.removedUsers = deletedPs != null 11759 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 11760 : null; 11761 } 11762 } 11763 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11764 removeDataDirsLI(ps.volumeUuid, packageName); 11765 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 11766 } 11767 // writer 11768 synchronized (mPackages) { 11769 if (deletedPs != null) { 11770 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11771 if (outInfo != null) { 11772 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 11773 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 11774 } 11775 updatePermissionsLPw(deletedPs.name, null, 0); 11776 if (deletedPs.sharedUser != null) { 11777 // Remove permissions associated with package. Since runtime 11778 // permissions are per user we have to kill the removed package 11779 // or packages running under the shared user of the removed 11780 // package if revoking the permissions requested only by the removed 11781 // package is successful and this causes a change in gids. 11782 for (int userId : UserManagerService.getInstance().getUserIds()) { 11783 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 11784 userId); 11785 if (userIdToKill == UserHandle.USER_ALL 11786 || userIdToKill >= UserHandle.USER_OWNER) { 11787 // If gids changed for this user, kill all affected packages. 11788 mHandler.post(new Runnable() { 11789 @Override 11790 public void run() { 11791 // This has to happen with no lock held. 11792 killSettingPackagesForUser(deletedPs, userIdToKill, 11793 KILL_APP_REASON_GIDS_CHANGED); 11794 } 11795 }); 11796 break; 11797 } 11798 } 11799 } 11800 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 11801 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 11802 } 11803 // make sure to preserve per-user disabled state if this removal was just 11804 // a downgrade of a system app to the factory package 11805 if (allUserHandles != null && perUserInstalled != null) { 11806 if (DEBUG_REMOVE) { 11807 Slog.d(TAG, "Propagating install state across downgrade"); 11808 } 11809 for (int i = 0; i < allUserHandles.length; i++) { 11810 if (DEBUG_REMOVE) { 11811 Slog.d(TAG, " user " + allUserHandles[i] 11812 + " => " + perUserInstalled[i]); 11813 } 11814 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 11815 } 11816 } 11817 } 11818 // can downgrade to reader 11819 if (writeSettings) { 11820 // Save settings now 11821 mSettings.writeLPr(); 11822 } 11823 } 11824 if (outInfo != null) { 11825 // A user ID was deleted here. Go through all users and remove it 11826 // from KeyStore. 11827 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 11828 } 11829 } 11830 11831 static boolean locationIsPrivileged(File path) { 11832 try { 11833 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 11834 .getCanonicalPath(); 11835 return path.getCanonicalPath().startsWith(privilegedAppDir); 11836 } catch (IOException e) { 11837 Slog.e(TAG, "Unable to access code path " + path); 11838 } 11839 return false; 11840 } 11841 11842 /* 11843 * Tries to delete system package. 11844 */ 11845 private boolean deleteSystemPackageLI(PackageSetting newPs, 11846 int[] allUserHandles, boolean[] perUserInstalled, 11847 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 11848 final boolean applyUserRestrictions 11849 = (allUserHandles != null) && (perUserInstalled != null); 11850 PackageSetting disabledPs = null; 11851 // Confirm if the system package has been updated 11852 // An updated system app can be deleted. This will also have to restore 11853 // the system pkg from system partition 11854 // reader 11855 synchronized (mPackages) { 11856 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 11857 } 11858 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 11859 + " disabledPs=" + disabledPs); 11860 if (disabledPs == null) { 11861 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 11862 return false; 11863 } else if (DEBUG_REMOVE) { 11864 Slog.d(TAG, "Deleting system pkg from data partition"); 11865 } 11866 if (DEBUG_REMOVE) { 11867 if (applyUserRestrictions) { 11868 Slog.d(TAG, "Remembering install states:"); 11869 for (int i = 0; i < allUserHandles.length; i++) { 11870 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 11871 } 11872 } 11873 } 11874 // Delete the updated package 11875 outInfo.isRemovedPackageSystemUpdate = true; 11876 if (disabledPs.versionCode < newPs.versionCode) { 11877 // Delete data for downgrades 11878 flags &= ~PackageManager.DELETE_KEEP_DATA; 11879 } else { 11880 // Preserve data by setting flag 11881 flags |= PackageManager.DELETE_KEEP_DATA; 11882 } 11883 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 11884 allUserHandles, perUserInstalled, outInfo, writeSettings); 11885 if (!ret) { 11886 return false; 11887 } 11888 // writer 11889 synchronized (mPackages) { 11890 // Reinstate the old system package 11891 mSettings.enableSystemPackageLPw(newPs.name); 11892 // Remove any native libraries from the upgraded package. 11893 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 11894 } 11895 // Install the system package 11896 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 11897 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 11898 if (locationIsPrivileged(disabledPs.codePath)) { 11899 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 11900 } 11901 11902 final PackageParser.Package newPkg; 11903 try { 11904 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 11905 } catch (PackageManagerException e) { 11906 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 11907 return false; 11908 } 11909 11910 // writer 11911 synchronized (mPackages) { 11912 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 11913 updatePermissionsLPw(newPkg.packageName, newPkg, 11914 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 11915 if (applyUserRestrictions) { 11916 if (DEBUG_REMOVE) { 11917 Slog.d(TAG, "Propagating install state across reinstall"); 11918 } 11919 for (int i = 0; i < allUserHandles.length; i++) { 11920 if (DEBUG_REMOVE) { 11921 Slog.d(TAG, " user " + allUserHandles[i] 11922 + " => " + perUserInstalled[i]); 11923 } 11924 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 11925 } 11926 // Regardless of writeSettings we need to ensure that this restriction 11927 // state propagation is persisted 11928 mSettings.writeAllUsersPackageRestrictionsLPr(); 11929 } 11930 // can downgrade to reader here 11931 if (writeSettings) { 11932 mSettings.writeLPr(); 11933 } 11934 } 11935 return true; 11936 } 11937 11938 private boolean deleteInstalledPackageLI(PackageSetting ps, 11939 boolean deleteCodeAndResources, int flags, 11940 int[] allUserHandles, boolean[] perUserInstalled, 11941 PackageRemovedInfo outInfo, boolean writeSettings) { 11942 if (outInfo != null) { 11943 outInfo.uid = ps.appId; 11944 } 11945 11946 // Delete package data from internal structures and also remove data if flag is set 11947 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 11948 11949 // Delete application code and resources 11950 if (deleteCodeAndResources && (outInfo != null)) { 11951 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 11952 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 11953 getAppDexInstructionSets(ps)); 11954 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 11955 } 11956 return true; 11957 } 11958 11959 @Override 11960 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 11961 int userId) { 11962 mContext.enforceCallingOrSelfPermission( 11963 android.Manifest.permission.DELETE_PACKAGES, null); 11964 synchronized (mPackages) { 11965 PackageSetting ps = mSettings.mPackages.get(packageName); 11966 if (ps == null) { 11967 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 11968 return false; 11969 } 11970 if (!ps.getInstalled(userId)) { 11971 // Can't block uninstall for an app that is not installed or enabled. 11972 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 11973 return false; 11974 } 11975 ps.setBlockUninstall(blockUninstall, userId); 11976 mSettings.writePackageRestrictionsLPr(userId); 11977 } 11978 return true; 11979 } 11980 11981 @Override 11982 public boolean getBlockUninstallForUser(String packageName, int userId) { 11983 synchronized (mPackages) { 11984 PackageSetting ps = mSettings.mPackages.get(packageName); 11985 if (ps == null) { 11986 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 11987 return false; 11988 } 11989 return ps.getBlockUninstall(userId); 11990 } 11991 } 11992 11993 /* 11994 * This method handles package deletion in general 11995 */ 11996 private boolean deletePackageLI(String packageName, UserHandle user, 11997 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 11998 int flags, PackageRemovedInfo outInfo, 11999 boolean writeSettings) { 12000 if (packageName == null) { 12001 Slog.w(TAG, "Attempt to delete null packageName."); 12002 return false; 12003 } 12004 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 12005 PackageSetting ps; 12006 boolean dataOnly = false; 12007 int removeUser = -1; 12008 int appId = -1; 12009 synchronized (mPackages) { 12010 ps = mSettings.mPackages.get(packageName); 12011 if (ps == null) { 12012 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 12013 return false; 12014 } 12015 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 12016 && user.getIdentifier() != UserHandle.USER_ALL) { 12017 // The caller is asking that the package only be deleted for a single 12018 // user. To do this, we just mark its uninstalled state and delete 12019 // its data. If this is a system app, we only allow this to happen if 12020 // they have set the special DELETE_SYSTEM_APP which requests different 12021 // semantics than normal for uninstalling system apps. 12022 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 12023 ps.setUserState(user.getIdentifier(), 12024 COMPONENT_ENABLED_STATE_DEFAULT, 12025 false, //installed 12026 true, //stopped 12027 true, //notLaunched 12028 false, //hidden 12029 null, null, null, 12030 false, // blockUninstall 12031 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 12032 if (!isSystemApp(ps)) { 12033 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 12034 // Other user still have this package installed, so all 12035 // we need to do is clear this user's data and save that 12036 // it is uninstalled. 12037 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 12038 removeUser = user.getIdentifier(); 12039 appId = ps.appId; 12040 scheduleWritePackageRestrictionsLocked(removeUser); 12041 } else { 12042 // We need to set it back to 'installed' so the uninstall 12043 // broadcasts will be sent correctly. 12044 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 12045 ps.setInstalled(true, user.getIdentifier()); 12046 } 12047 } else { 12048 // This is a system app, so we assume that the 12049 // other users still have this package installed, so all 12050 // we need to do is clear this user's data and save that 12051 // it is uninstalled. 12052 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 12053 removeUser = user.getIdentifier(); 12054 appId = ps.appId; 12055 scheduleWritePackageRestrictionsLocked(removeUser); 12056 } 12057 } 12058 } 12059 12060 if (removeUser >= 0) { 12061 // From above, we determined that we are deleting this only 12062 // for a single user. Continue the work here. 12063 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 12064 if (outInfo != null) { 12065 outInfo.removedPackage = packageName; 12066 outInfo.removedAppId = appId; 12067 outInfo.removedUsers = new int[] {removeUser}; 12068 } 12069 mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser); 12070 removeKeystoreDataIfNeeded(removeUser, appId); 12071 schedulePackageCleaning(packageName, removeUser, false); 12072 synchronized (mPackages) { 12073 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { 12074 scheduleWritePackageRestrictionsLocked(removeUser); 12075 } 12076 } 12077 return true; 12078 } 12079 12080 if (dataOnly) { 12081 // Delete application data first 12082 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 12083 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 12084 return true; 12085 } 12086 12087 boolean ret = false; 12088 if (isSystemApp(ps)) { 12089 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 12090 // When an updated system application is deleted we delete the existing resources as well and 12091 // fall back to existing code in system partition 12092 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 12093 flags, outInfo, writeSettings); 12094 } else { 12095 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 12096 // Kill application pre-emptively especially for apps on sd. 12097 killApplication(packageName, ps.appId, "uninstall pkg"); 12098 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 12099 allUserHandles, perUserInstalled, 12100 outInfo, writeSettings); 12101 } 12102 12103 return ret; 12104 } 12105 12106 private final class ClearStorageConnection implements ServiceConnection { 12107 IMediaContainerService mContainerService; 12108 12109 @Override 12110 public void onServiceConnected(ComponentName name, IBinder service) { 12111 synchronized (this) { 12112 mContainerService = IMediaContainerService.Stub.asInterface(service); 12113 notifyAll(); 12114 } 12115 } 12116 12117 @Override 12118 public void onServiceDisconnected(ComponentName name) { 12119 } 12120 } 12121 12122 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 12123 final boolean mounted; 12124 if (Environment.isExternalStorageEmulated()) { 12125 mounted = true; 12126 } else { 12127 final String status = Environment.getExternalStorageState(); 12128 12129 mounted = status.equals(Environment.MEDIA_MOUNTED) 12130 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 12131 } 12132 12133 if (!mounted) { 12134 return; 12135 } 12136 12137 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 12138 int[] users; 12139 if (userId == UserHandle.USER_ALL) { 12140 users = sUserManager.getUserIds(); 12141 } else { 12142 users = new int[] { userId }; 12143 } 12144 final ClearStorageConnection conn = new ClearStorageConnection(); 12145 if (mContext.bindServiceAsUser( 12146 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 12147 try { 12148 for (int curUser : users) { 12149 long timeout = SystemClock.uptimeMillis() + 5000; 12150 synchronized (conn) { 12151 long now = SystemClock.uptimeMillis(); 12152 while (conn.mContainerService == null && now < timeout) { 12153 try { 12154 conn.wait(timeout - now); 12155 } catch (InterruptedException e) { 12156 } 12157 } 12158 } 12159 if (conn.mContainerService == null) { 12160 return; 12161 } 12162 12163 final UserEnvironment userEnv = new UserEnvironment(curUser); 12164 clearDirectory(conn.mContainerService, 12165 userEnv.buildExternalStorageAppCacheDirs(packageName)); 12166 if (allData) { 12167 clearDirectory(conn.mContainerService, 12168 userEnv.buildExternalStorageAppDataDirs(packageName)); 12169 clearDirectory(conn.mContainerService, 12170 userEnv.buildExternalStorageAppMediaDirs(packageName)); 12171 } 12172 } 12173 } finally { 12174 mContext.unbindService(conn); 12175 } 12176 } 12177 } 12178 12179 @Override 12180 public void clearApplicationUserData(final String packageName, 12181 final IPackageDataObserver observer, final int userId) { 12182 mContext.enforceCallingOrSelfPermission( 12183 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 12184 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 12185 // Queue up an async operation since the package deletion may take a little while. 12186 mHandler.post(new Runnable() { 12187 public void run() { 12188 mHandler.removeCallbacks(this); 12189 final boolean succeeded; 12190 synchronized (mInstallLock) { 12191 succeeded = clearApplicationUserDataLI(packageName, userId); 12192 } 12193 clearExternalStorageDataSync(packageName, userId, true); 12194 if (succeeded) { 12195 // invoke DeviceStorageMonitor's update method to clear any notifications 12196 DeviceStorageMonitorInternal 12197 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 12198 if (dsm != null) { 12199 dsm.checkMemory(); 12200 } 12201 } 12202 if(observer != null) { 12203 try { 12204 observer.onRemoveCompleted(packageName, succeeded); 12205 } catch (RemoteException e) { 12206 Log.i(TAG, "Observer no longer exists."); 12207 } 12208 } //end if observer 12209 } //end run 12210 }); 12211 } 12212 12213 private boolean clearApplicationUserDataLI(String packageName, int userId) { 12214 if (packageName == null) { 12215 Slog.w(TAG, "Attempt to delete null packageName."); 12216 return false; 12217 } 12218 12219 // Try finding details about the requested package 12220 PackageParser.Package pkg; 12221 synchronized (mPackages) { 12222 pkg = mPackages.get(packageName); 12223 if (pkg == null) { 12224 final PackageSetting ps = mSettings.mPackages.get(packageName); 12225 if (ps != null) { 12226 pkg = ps.pkg; 12227 } 12228 } 12229 } 12230 12231 if (pkg == null) { 12232 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 12233 } 12234 12235 // Always delete data directories for package, even if we found no other 12236 // record of app. This helps users recover from UID mismatches without 12237 // resorting to a full data wipe. 12238 int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId); 12239 if (retCode < 0) { 12240 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 12241 return false; 12242 } 12243 12244 if (pkg == null) { 12245 return false; 12246 } 12247 12248 if (pkg != null && pkg.applicationInfo != null) { 12249 final int appId = pkg.applicationInfo.uid; 12250 removeKeystoreDataIfNeeded(userId, appId); 12251 } 12252 12253 // Create a native library symlink only if we have native libraries 12254 // and if the native libraries are 32 bit libraries. We do not provide 12255 // this symlink for 64 bit libraries. 12256 if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null && 12257 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 12258 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 12259 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 12260 nativeLibPath, userId) < 0) { 12261 Slog.w(TAG, "Failed linking native library dir"); 12262 return false; 12263 } 12264 } 12265 12266 return true; 12267 } 12268 12269 /** 12270 * Remove entries from the keystore daemon. Will only remove it if the 12271 * {@code appId} is valid. 12272 */ 12273 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 12274 if (appId < 0) { 12275 return; 12276 } 12277 12278 final KeyStore keyStore = KeyStore.getInstance(); 12279 if (keyStore != null) { 12280 if (userId == UserHandle.USER_ALL) { 12281 for (final int individual : sUserManager.getUserIds()) { 12282 keyStore.clearUid(UserHandle.getUid(individual, appId)); 12283 } 12284 } else { 12285 keyStore.clearUid(UserHandle.getUid(userId, appId)); 12286 } 12287 } else { 12288 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 12289 } 12290 } 12291 12292 @Override 12293 public void deleteApplicationCacheFiles(final String packageName, 12294 final IPackageDataObserver observer) { 12295 mContext.enforceCallingOrSelfPermission( 12296 android.Manifest.permission.DELETE_CACHE_FILES, null); 12297 // Queue up an async operation since the package deletion may take a little while. 12298 final int userId = UserHandle.getCallingUserId(); 12299 mHandler.post(new Runnable() { 12300 public void run() { 12301 mHandler.removeCallbacks(this); 12302 final boolean succeded; 12303 synchronized (mInstallLock) { 12304 succeded = deleteApplicationCacheFilesLI(packageName, userId); 12305 } 12306 clearExternalStorageDataSync(packageName, userId, false); 12307 if(observer != null) { 12308 try { 12309 observer.onRemoveCompleted(packageName, succeded); 12310 } catch (RemoteException e) { 12311 Log.i(TAG, "Observer no longer exists."); 12312 } 12313 } //end if observer 12314 } //end run 12315 }); 12316 } 12317 12318 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 12319 if (packageName == null) { 12320 Slog.w(TAG, "Attempt to delete null packageName."); 12321 return false; 12322 } 12323 PackageParser.Package p; 12324 synchronized (mPackages) { 12325 p = mPackages.get(packageName); 12326 } 12327 if (p == null) { 12328 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12329 return false; 12330 } 12331 final ApplicationInfo applicationInfo = p.applicationInfo; 12332 if (applicationInfo == null) { 12333 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12334 return false; 12335 } 12336 int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId); 12337 if (retCode < 0) { 12338 Slog.w(TAG, "Couldn't remove cache files for package: " 12339 + packageName + " u" + userId); 12340 return false; 12341 } 12342 return true; 12343 } 12344 12345 @Override 12346 public void getPackageSizeInfo(final String packageName, int userHandle, 12347 final IPackageStatsObserver observer) { 12348 mContext.enforceCallingOrSelfPermission( 12349 android.Manifest.permission.GET_PACKAGE_SIZE, null); 12350 if (packageName == null) { 12351 throw new IllegalArgumentException("Attempt to get size of null packageName"); 12352 } 12353 12354 PackageStats stats = new PackageStats(packageName, userHandle); 12355 12356 /* 12357 * Queue up an async operation since the package measurement may take a 12358 * little while. 12359 */ 12360 Message msg = mHandler.obtainMessage(INIT_COPY); 12361 msg.obj = new MeasureParams(stats, observer); 12362 mHandler.sendMessage(msg); 12363 } 12364 12365 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 12366 PackageStats pStats) { 12367 if (packageName == null) { 12368 Slog.w(TAG, "Attempt to get size of null packageName."); 12369 return false; 12370 } 12371 PackageParser.Package p; 12372 boolean dataOnly = false; 12373 String libDirRoot = null; 12374 String asecPath = null; 12375 PackageSetting ps = null; 12376 synchronized (mPackages) { 12377 p = mPackages.get(packageName); 12378 ps = mSettings.mPackages.get(packageName); 12379 if(p == null) { 12380 dataOnly = true; 12381 if((ps == null) || (ps.pkg == null)) { 12382 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12383 return false; 12384 } 12385 p = ps.pkg; 12386 } 12387 if (ps != null) { 12388 libDirRoot = ps.legacyNativeLibraryPathString; 12389 } 12390 if (p != null && (isExternal(p) || p.isForwardLocked())) { 12391 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 12392 if (secureContainerId != null) { 12393 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 12394 } 12395 } 12396 } 12397 String publicSrcDir = null; 12398 if(!dataOnly) { 12399 final ApplicationInfo applicationInfo = p.applicationInfo; 12400 if (applicationInfo == null) { 12401 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12402 return false; 12403 } 12404 if (p.isForwardLocked()) { 12405 publicSrcDir = applicationInfo.getBaseResourcePath(); 12406 } 12407 } 12408 // TODO: extend to measure size of split APKs 12409 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 12410 // not just the first level. 12411 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 12412 // just the primary. 12413 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 12414 int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath, 12415 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 12416 if (res < 0) { 12417 return false; 12418 } 12419 12420 // Fix-up for forward-locked applications in ASEC containers. 12421 if (!isExternal(p)) { 12422 pStats.codeSize += pStats.externalCodeSize; 12423 pStats.externalCodeSize = 0L; 12424 } 12425 12426 return true; 12427 } 12428 12429 12430 @Override 12431 public void addPackageToPreferred(String packageName) { 12432 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 12433 } 12434 12435 @Override 12436 public void removePackageFromPreferred(String packageName) { 12437 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 12438 } 12439 12440 @Override 12441 public List<PackageInfo> getPreferredPackages(int flags) { 12442 return new ArrayList<PackageInfo>(); 12443 } 12444 12445 private int getUidTargetSdkVersionLockedLPr(int uid) { 12446 Object obj = mSettings.getUserIdLPr(uid); 12447 if (obj instanceof SharedUserSetting) { 12448 final SharedUserSetting sus = (SharedUserSetting) obj; 12449 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 12450 final Iterator<PackageSetting> it = sus.packages.iterator(); 12451 while (it.hasNext()) { 12452 final PackageSetting ps = it.next(); 12453 if (ps.pkg != null) { 12454 int v = ps.pkg.applicationInfo.targetSdkVersion; 12455 if (v < vers) vers = v; 12456 } 12457 } 12458 return vers; 12459 } else if (obj instanceof PackageSetting) { 12460 final PackageSetting ps = (PackageSetting) obj; 12461 if (ps.pkg != null) { 12462 return ps.pkg.applicationInfo.targetSdkVersion; 12463 } 12464 } 12465 return Build.VERSION_CODES.CUR_DEVELOPMENT; 12466 } 12467 12468 @Override 12469 public void addPreferredActivity(IntentFilter filter, int match, 12470 ComponentName[] set, ComponentName activity, int userId) { 12471 addPreferredActivityInternal(filter, match, set, activity, true, userId, 12472 "Adding preferred"); 12473 } 12474 12475 private void addPreferredActivityInternal(IntentFilter filter, int match, 12476 ComponentName[] set, ComponentName activity, boolean always, int userId, 12477 String opname) { 12478 // writer 12479 int callingUid = Binder.getCallingUid(); 12480 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 12481 if (filter.countActions() == 0) { 12482 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 12483 return; 12484 } 12485 synchronized (mPackages) { 12486 if (mContext.checkCallingOrSelfPermission( 12487 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12488 != PackageManager.PERMISSION_GRANTED) { 12489 if (getUidTargetSdkVersionLockedLPr(callingUid) 12490 < Build.VERSION_CODES.FROYO) { 12491 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 12492 + callingUid); 12493 return; 12494 } 12495 mContext.enforceCallingOrSelfPermission( 12496 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12497 } 12498 12499 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 12500 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 12501 + userId + ":"); 12502 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12503 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 12504 scheduleWritePackageRestrictionsLocked(userId); 12505 } 12506 } 12507 12508 @Override 12509 public void replacePreferredActivity(IntentFilter filter, int match, 12510 ComponentName[] set, ComponentName activity, int userId) { 12511 if (filter.countActions() != 1) { 12512 throw new IllegalArgumentException( 12513 "replacePreferredActivity expects filter to have only 1 action."); 12514 } 12515 if (filter.countDataAuthorities() != 0 12516 || filter.countDataPaths() != 0 12517 || filter.countDataSchemes() > 1 12518 || filter.countDataTypes() != 0) { 12519 throw new IllegalArgumentException( 12520 "replacePreferredActivity expects filter to have no data authorities, " + 12521 "paths, or types; and at most one scheme."); 12522 } 12523 12524 final int callingUid = Binder.getCallingUid(); 12525 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 12526 synchronized (mPackages) { 12527 if (mContext.checkCallingOrSelfPermission( 12528 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12529 != PackageManager.PERMISSION_GRANTED) { 12530 if (getUidTargetSdkVersionLockedLPr(callingUid) 12531 < Build.VERSION_CODES.FROYO) { 12532 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 12533 + Binder.getCallingUid()); 12534 return; 12535 } 12536 mContext.enforceCallingOrSelfPermission( 12537 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12538 } 12539 12540 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 12541 if (pir != null) { 12542 // Get all of the existing entries that exactly match this filter. 12543 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 12544 if (existing != null && existing.size() == 1) { 12545 PreferredActivity cur = existing.get(0); 12546 if (DEBUG_PREFERRED) { 12547 Slog.i(TAG, "Checking replace of preferred:"); 12548 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12549 if (!cur.mPref.mAlways) { 12550 Slog.i(TAG, " -- CUR; not mAlways!"); 12551 } else { 12552 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 12553 Slog.i(TAG, " -- CUR: mSet=" 12554 + Arrays.toString(cur.mPref.mSetComponents)); 12555 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 12556 Slog.i(TAG, " -- NEW: mMatch=" 12557 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 12558 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 12559 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 12560 } 12561 } 12562 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 12563 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 12564 && cur.mPref.sameSet(set)) { 12565 // Setting the preferred activity to what it happens to be already 12566 if (DEBUG_PREFERRED) { 12567 Slog.i(TAG, "Replacing with same preferred activity " 12568 + cur.mPref.mShortComponent + " for user " 12569 + userId + ":"); 12570 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12571 } 12572 return; 12573 } 12574 } 12575 12576 if (existing != null) { 12577 if (DEBUG_PREFERRED) { 12578 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 12579 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12580 } 12581 for (int i = 0; i < existing.size(); i++) { 12582 PreferredActivity pa = existing.get(i); 12583 if (DEBUG_PREFERRED) { 12584 Slog.i(TAG, "Removing existing preferred activity " 12585 + pa.mPref.mComponent + ":"); 12586 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 12587 } 12588 pir.removeFilter(pa); 12589 } 12590 } 12591 } 12592 addPreferredActivityInternal(filter, match, set, activity, true, userId, 12593 "Replacing preferred"); 12594 } 12595 } 12596 12597 @Override 12598 public void clearPackagePreferredActivities(String packageName) { 12599 final int uid = Binder.getCallingUid(); 12600 // writer 12601 synchronized (mPackages) { 12602 PackageParser.Package pkg = mPackages.get(packageName); 12603 if (pkg == null || pkg.applicationInfo.uid != uid) { 12604 if (mContext.checkCallingOrSelfPermission( 12605 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12606 != PackageManager.PERMISSION_GRANTED) { 12607 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 12608 < Build.VERSION_CODES.FROYO) { 12609 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 12610 + Binder.getCallingUid()); 12611 return; 12612 } 12613 mContext.enforceCallingOrSelfPermission( 12614 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12615 } 12616 } 12617 12618 int user = UserHandle.getCallingUserId(); 12619 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 12620 scheduleWritePackageRestrictionsLocked(user); 12621 } 12622 } 12623 } 12624 12625 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 12626 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 12627 ArrayList<PreferredActivity> removed = null; 12628 boolean changed = false; 12629 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 12630 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 12631 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 12632 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 12633 continue; 12634 } 12635 Iterator<PreferredActivity> it = pir.filterIterator(); 12636 while (it.hasNext()) { 12637 PreferredActivity pa = it.next(); 12638 // Mark entry for removal only if it matches the package name 12639 // and the entry is of type "always". 12640 if (packageName == null || 12641 (pa.mPref.mComponent.getPackageName().equals(packageName) 12642 && pa.mPref.mAlways)) { 12643 if (removed == null) { 12644 removed = new ArrayList<PreferredActivity>(); 12645 } 12646 removed.add(pa); 12647 } 12648 } 12649 if (removed != null) { 12650 for (int j=0; j<removed.size(); j++) { 12651 PreferredActivity pa = removed.get(j); 12652 pir.removeFilter(pa); 12653 } 12654 changed = true; 12655 } 12656 } 12657 return changed; 12658 } 12659 12660 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 12661 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 12662 if (userId == UserHandle.USER_ALL) { 12663 mSettings.removeIntentFilterVerificationLPw(packageName, sUserManager.getUserIds()); 12664 for (int oneUserId : sUserManager.getUserIds()) { 12665 scheduleWritePackageRestrictionsLocked(oneUserId); 12666 } 12667 } else { 12668 mSettings.removeIntentFilterVerificationLPw(packageName, userId); 12669 scheduleWritePackageRestrictionsLocked(userId); 12670 } 12671 } 12672 12673 @Override 12674 public void resetPreferredActivities(int userId) { 12675 /* TODO: Actually use userId. Why is it being passed in? */ 12676 mContext.enforceCallingOrSelfPermission( 12677 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12678 // writer 12679 synchronized (mPackages) { 12680 int user = UserHandle.getCallingUserId(); 12681 clearPackagePreferredActivitiesLPw(null, user); 12682 mSettings.readDefaultPreferredAppsLPw(this, user); 12683 scheduleWritePackageRestrictionsLocked(user); 12684 } 12685 } 12686 12687 @Override 12688 public int getPreferredActivities(List<IntentFilter> outFilters, 12689 List<ComponentName> outActivities, String packageName) { 12690 12691 int num = 0; 12692 final int userId = UserHandle.getCallingUserId(); 12693 // reader 12694 synchronized (mPackages) { 12695 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 12696 if (pir != null) { 12697 final Iterator<PreferredActivity> it = pir.filterIterator(); 12698 while (it.hasNext()) { 12699 final PreferredActivity pa = it.next(); 12700 if (packageName == null 12701 || (pa.mPref.mComponent.getPackageName().equals(packageName) 12702 && pa.mPref.mAlways)) { 12703 if (outFilters != null) { 12704 outFilters.add(new IntentFilter(pa)); 12705 } 12706 if (outActivities != null) { 12707 outActivities.add(pa.mPref.mComponent); 12708 } 12709 } 12710 } 12711 } 12712 } 12713 12714 return num; 12715 } 12716 12717 @Override 12718 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 12719 int userId) { 12720 int callingUid = Binder.getCallingUid(); 12721 if (callingUid != Process.SYSTEM_UID) { 12722 throw new SecurityException( 12723 "addPersistentPreferredActivity can only be run by the system"); 12724 } 12725 if (filter.countActions() == 0) { 12726 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 12727 return; 12728 } 12729 synchronized (mPackages) { 12730 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 12731 " :"); 12732 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12733 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 12734 new PersistentPreferredActivity(filter, activity)); 12735 scheduleWritePackageRestrictionsLocked(userId); 12736 } 12737 } 12738 12739 @Override 12740 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 12741 int callingUid = Binder.getCallingUid(); 12742 if (callingUid != Process.SYSTEM_UID) { 12743 throw new SecurityException( 12744 "clearPackagePersistentPreferredActivities can only be run by the system"); 12745 } 12746 ArrayList<PersistentPreferredActivity> removed = null; 12747 boolean changed = false; 12748 synchronized (mPackages) { 12749 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 12750 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 12751 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 12752 .valueAt(i); 12753 if (userId != thisUserId) { 12754 continue; 12755 } 12756 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 12757 while (it.hasNext()) { 12758 PersistentPreferredActivity ppa = it.next(); 12759 // Mark entry for removal only if it matches the package name. 12760 if (ppa.mComponent.getPackageName().equals(packageName)) { 12761 if (removed == null) { 12762 removed = new ArrayList<PersistentPreferredActivity>(); 12763 } 12764 removed.add(ppa); 12765 } 12766 } 12767 if (removed != null) { 12768 for (int j=0; j<removed.size(); j++) { 12769 PersistentPreferredActivity ppa = removed.get(j); 12770 ppir.removeFilter(ppa); 12771 } 12772 changed = true; 12773 } 12774 } 12775 12776 if (changed) { 12777 scheduleWritePackageRestrictionsLocked(userId); 12778 } 12779 } 12780 } 12781 12782 /** 12783 * Non-Binder method, support for the backup/restore mechanism: write the 12784 * full set of preferred activities in its canonical XML format. Returns true 12785 * on success; false otherwise. 12786 */ 12787 @Override 12788 public byte[] getPreferredActivityBackup(int userId) { 12789 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12790 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 12791 } 12792 12793 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 12794 try { 12795 final XmlSerializer serializer = new FastXmlSerializer(); 12796 serializer.setOutput(dataStream, "utf-8"); 12797 serializer.startDocument(null, true); 12798 serializer.startTag(null, TAG_PREFERRED_BACKUP); 12799 12800 synchronized (mPackages) { 12801 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 12802 } 12803 12804 serializer.endTag(null, TAG_PREFERRED_BACKUP); 12805 serializer.endDocument(); 12806 serializer.flush(); 12807 } catch (Exception e) { 12808 if (DEBUG_BACKUP) { 12809 Slog.e(TAG, "Unable to write preferred activities for backup", e); 12810 } 12811 return null; 12812 } 12813 12814 return dataStream.toByteArray(); 12815 } 12816 12817 @Override 12818 public void restorePreferredActivities(byte[] backup, int userId) { 12819 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12820 throw new SecurityException("Only the system may call restorePreferredActivities()"); 12821 } 12822 12823 try { 12824 final XmlPullParser parser = Xml.newPullParser(); 12825 parser.setInput(new ByteArrayInputStream(backup), null); 12826 12827 int type; 12828 while ((type = parser.next()) != XmlPullParser.START_TAG 12829 && type != XmlPullParser.END_DOCUMENT) { 12830 } 12831 if (type != XmlPullParser.START_TAG) { 12832 // oops didn't find a start tag?! 12833 if (DEBUG_BACKUP) { 12834 Slog.e(TAG, "Didn't find start tag during restore"); 12835 } 12836 return; 12837 } 12838 12839 // this is supposed to be TAG_PREFERRED_BACKUP 12840 if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) { 12841 if (DEBUG_BACKUP) { 12842 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 12843 } 12844 return; 12845 } 12846 12847 // skip interfering stuff, then we're aligned with the backing implementation 12848 while ((type = parser.next()) == XmlPullParser.TEXT) { } 12849 synchronized (mPackages) { 12850 mSettings.readPreferredActivitiesLPw(parser, userId); 12851 } 12852 } catch (Exception e) { 12853 if (DEBUG_BACKUP) { 12854 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 12855 } 12856 } 12857 } 12858 12859 @Override 12860 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 12861 int sourceUserId, int targetUserId, int flags) { 12862 mContext.enforceCallingOrSelfPermission( 12863 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 12864 int callingUid = Binder.getCallingUid(); 12865 enforceOwnerRights(ownerPackage, callingUid); 12866 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 12867 if (intentFilter.countActions() == 0) { 12868 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 12869 return; 12870 } 12871 synchronized (mPackages) { 12872 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 12873 ownerPackage, targetUserId, flags); 12874 CrossProfileIntentResolver resolver = 12875 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 12876 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 12877 // We have all those whose filter is equal. Now checking if the rest is equal as well. 12878 if (existing != null) { 12879 int size = existing.size(); 12880 for (int i = 0; i < size; i++) { 12881 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 12882 return; 12883 } 12884 } 12885 } 12886 resolver.addFilter(newFilter); 12887 scheduleWritePackageRestrictionsLocked(sourceUserId); 12888 } 12889 } 12890 12891 @Override 12892 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 12893 mContext.enforceCallingOrSelfPermission( 12894 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 12895 int callingUid = Binder.getCallingUid(); 12896 enforceOwnerRights(ownerPackage, callingUid); 12897 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 12898 synchronized (mPackages) { 12899 CrossProfileIntentResolver resolver = 12900 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 12901 ArraySet<CrossProfileIntentFilter> set = 12902 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 12903 for (CrossProfileIntentFilter filter : set) { 12904 if (filter.getOwnerPackage().equals(ownerPackage)) { 12905 resolver.removeFilter(filter); 12906 } 12907 } 12908 scheduleWritePackageRestrictionsLocked(sourceUserId); 12909 } 12910 } 12911 12912 // Enforcing that callingUid is owning pkg on userId 12913 private void enforceOwnerRights(String pkg, int callingUid) { 12914 // The system owns everything. 12915 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 12916 return; 12917 } 12918 int callingUserId = UserHandle.getUserId(callingUid); 12919 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 12920 if (pi == null) { 12921 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 12922 + callingUserId); 12923 } 12924 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 12925 throw new SecurityException("Calling uid " + callingUid 12926 + " does not own package " + pkg); 12927 } 12928 } 12929 12930 @Override 12931 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 12932 Intent intent = new Intent(Intent.ACTION_MAIN); 12933 intent.addCategory(Intent.CATEGORY_HOME); 12934 12935 final int callingUserId = UserHandle.getCallingUserId(); 12936 List<ResolveInfo> list = queryIntentActivities(intent, null, 12937 PackageManager.GET_META_DATA, callingUserId); 12938 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 12939 true, false, false, callingUserId); 12940 12941 allHomeCandidates.clear(); 12942 if (list != null) { 12943 for (ResolveInfo ri : list) { 12944 allHomeCandidates.add(ri); 12945 } 12946 } 12947 return (preferred == null || preferred.activityInfo == null) 12948 ? null 12949 : new ComponentName(preferred.activityInfo.packageName, 12950 preferred.activityInfo.name); 12951 } 12952 12953 @Override 12954 public void setApplicationEnabledSetting(String appPackageName, 12955 int newState, int flags, int userId, String callingPackage) { 12956 if (!sUserManager.exists(userId)) return; 12957 if (callingPackage == null) { 12958 callingPackage = Integer.toString(Binder.getCallingUid()); 12959 } 12960 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 12961 } 12962 12963 @Override 12964 public void setComponentEnabledSetting(ComponentName componentName, 12965 int newState, int flags, int userId) { 12966 if (!sUserManager.exists(userId)) return; 12967 setEnabledSetting(componentName.getPackageName(), 12968 componentName.getClassName(), newState, flags, userId, null); 12969 } 12970 12971 private void setEnabledSetting(final String packageName, String className, int newState, 12972 final int flags, int userId, String callingPackage) { 12973 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 12974 || newState == COMPONENT_ENABLED_STATE_ENABLED 12975 || newState == COMPONENT_ENABLED_STATE_DISABLED 12976 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 12977 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 12978 throw new IllegalArgumentException("Invalid new component state: " 12979 + newState); 12980 } 12981 PackageSetting pkgSetting; 12982 final int uid = Binder.getCallingUid(); 12983 final int permission = mContext.checkCallingOrSelfPermission( 12984 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 12985 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 12986 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 12987 boolean sendNow = false; 12988 boolean isApp = (className == null); 12989 String componentName = isApp ? packageName : className; 12990 int packageUid = -1; 12991 ArrayList<String> components; 12992 12993 // writer 12994 synchronized (mPackages) { 12995 pkgSetting = mSettings.mPackages.get(packageName); 12996 if (pkgSetting == null) { 12997 if (className == null) { 12998 throw new IllegalArgumentException( 12999 "Unknown package: " + packageName); 13000 } 13001 throw new IllegalArgumentException( 13002 "Unknown component: " + packageName 13003 + "/" + className); 13004 } 13005 // Allow root and verify that userId is not being specified by a different user 13006 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 13007 throw new SecurityException( 13008 "Permission Denial: attempt to change component state from pid=" 13009 + Binder.getCallingPid() 13010 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 13011 } 13012 if (className == null) { 13013 // We're dealing with an application/package level state change 13014 if (pkgSetting.getEnabled(userId) == newState) { 13015 // Nothing to do 13016 return; 13017 } 13018 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 13019 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 13020 // Don't care about who enables an app. 13021 callingPackage = null; 13022 } 13023 pkgSetting.setEnabled(newState, userId, callingPackage); 13024 // pkgSetting.pkg.mSetEnabled = newState; 13025 } else { 13026 // We're dealing with a component level state change 13027 // First, verify that this is a valid class name. 13028 PackageParser.Package pkg = pkgSetting.pkg; 13029 if (pkg == null || !pkg.hasComponentClassName(className)) { 13030 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 13031 throw new IllegalArgumentException("Component class " + className 13032 + " does not exist in " + packageName); 13033 } else { 13034 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 13035 + className + " does not exist in " + packageName); 13036 } 13037 } 13038 switch (newState) { 13039 case COMPONENT_ENABLED_STATE_ENABLED: 13040 if (!pkgSetting.enableComponentLPw(className, userId)) { 13041 return; 13042 } 13043 break; 13044 case COMPONENT_ENABLED_STATE_DISABLED: 13045 if (!pkgSetting.disableComponentLPw(className, userId)) { 13046 return; 13047 } 13048 break; 13049 case COMPONENT_ENABLED_STATE_DEFAULT: 13050 if (!pkgSetting.restoreComponentLPw(className, userId)) { 13051 return; 13052 } 13053 break; 13054 default: 13055 Slog.e(TAG, "Invalid new component state: " + newState); 13056 return; 13057 } 13058 } 13059 scheduleWritePackageRestrictionsLocked(userId); 13060 components = mPendingBroadcasts.get(userId, packageName); 13061 final boolean newPackage = components == null; 13062 if (newPackage) { 13063 components = new ArrayList<String>(); 13064 } 13065 if (!components.contains(componentName)) { 13066 components.add(componentName); 13067 } 13068 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 13069 sendNow = true; 13070 // Purge entry from pending broadcast list if another one exists already 13071 // since we are sending one right away. 13072 mPendingBroadcasts.remove(userId, packageName); 13073 } else { 13074 if (newPackage) { 13075 mPendingBroadcasts.put(userId, packageName, components); 13076 } 13077 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 13078 // Schedule a message 13079 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 13080 } 13081 } 13082 } 13083 13084 long callingId = Binder.clearCallingIdentity(); 13085 try { 13086 if (sendNow) { 13087 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 13088 sendPackageChangedBroadcast(packageName, 13089 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 13090 } 13091 } finally { 13092 Binder.restoreCallingIdentity(callingId); 13093 } 13094 } 13095 13096 private void sendPackageChangedBroadcast(String packageName, 13097 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 13098 if (DEBUG_INSTALL) 13099 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 13100 + componentNames); 13101 Bundle extras = new Bundle(4); 13102 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 13103 String nameList[] = new String[componentNames.size()]; 13104 componentNames.toArray(nameList); 13105 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 13106 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 13107 extras.putInt(Intent.EXTRA_UID, packageUid); 13108 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 13109 new int[] {UserHandle.getUserId(packageUid)}); 13110 } 13111 13112 @Override 13113 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 13114 if (!sUserManager.exists(userId)) return; 13115 final int uid = Binder.getCallingUid(); 13116 final int permission = mContext.checkCallingOrSelfPermission( 13117 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 13118 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 13119 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 13120 // writer 13121 synchronized (mPackages) { 13122 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, 13123 uid, userId)) { 13124 scheduleWritePackageRestrictionsLocked(userId); 13125 } 13126 } 13127 } 13128 13129 @Override 13130 public String getInstallerPackageName(String packageName) { 13131 // reader 13132 synchronized (mPackages) { 13133 return mSettings.getInstallerPackageNameLPr(packageName); 13134 } 13135 } 13136 13137 @Override 13138 public int getApplicationEnabledSetting(String packageName, int userId) { 13139 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13140 int uid = Binder.getCallingUid(); 13141 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 13142 // reader 13143 synchronized (mPackages) { 13144 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 13145 } 13146 } 13147 13148 @Override 13149 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 13150 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13151 int uid = Binder.getCallingUid(); 13152 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 13153 // reader 13154 synchronized (mPackages) { 13155 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 13156 } 13157 } 13158 13159 @Override 13160 public void enterSafeMode() { 13161 enforceSystemOrRoot("Only the system can request entering safe mode"); 13162 13163 if (!mSystemReady) { 13164 mSafeMode = true; 13165 } 13166 } 13167 13168 @Override 13169 public void systemReady() { 13170 mSystemReady = true; 13171 13172 // Read the compatibilty setting when the system is ready. 13173 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 13174 mContext.getContentResolver(), 13175 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 13176 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 13177 if (DEBUG_SETTINGS) { 13178 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 13179 } 13180 13181 synchronized (mPackages) { 13182 // Verify that all of the preferred activity components actually 13183 // exist. It is possible for applications to be updated and at 13184 // that point remove a previously declared activity component that 13185 // had been set as a preferred activity. We try to clean this up 13186 // the next time we encounter that preferred activity, but it is 13187 // possible for the user flow to never be able to return to that 13188 // situation so here we do a sanity check to make sure we haven't 13189 // left any junk around. 13190 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 13191 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13192 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13193 removed.clear(); 13194 for (PreferredActivity pa : pir.filterSet()) { 13195 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 13196 removed.add(pa); 13197 } 13198 } 13199 if (removed.size() > 0) { 13200 for (int r=0; r<removed.size(); r++) { 13201 PreferredActivity pa = removed.get(r); 13202 Slog.w(TAG, "Removing dangling preferred activity: " 13203 + pa.mPref.mComponent); 13204 pir.removeFilter(pa); 13205 } 13206 mSettings.writePackageRestrictionsLPr( 13207 mSettings.mPreferredActivities.keyAt(i)); 13208 } 13209 } 13210 } 13211 sUserManager.systemReady(); 13212 13213 // Kick off any messages waiting for system ready 13214 if (mPostSystemReadyMessages != null) { 13215 for (Message msg : mPostSystemReadyMessages) { 13216 msg.sendToTarget(); 13217 } 13218 mPostSystemReadyMessages = null; 13219 } 13220 13221 // Watch for external volumes that come and go over time 13222 final StorageManager storage = mContext.getSystemService(StorageManager.class); 13223 storage.registerListener(mStorageListener); 13224 13225 mInstallerService.systemReady(); 13226 } 13227 13228 @Override 13229 public boolean isSafeMode() { 13230 return mSafeMode; 13231 } 13232 13233 @Override 13234 public boolean hasSystemUidErrors() { 13235 return mHasSystemUidErrors; 13236 } 13237 13238 static String arrayToString(int[] array) { 13239 StringBuffer buf = new StringBuffer(128); 13240 buf.append('['); 13241 if (array != null) { 13242 for (int i=0; i<array.length; i++) { 13243 if (i > 0) buf.append(", "); 13244 buf.append(array[i]); 13245 } 13246 } 13247 buf.append(']'); 13248 return buf.toString(); 13249 } 13250 13251 static class DumpState { 13252 public static final int DUMP_LIBS = 1 << 0; 13253 public static final int DUMP_FEATURES = 1 << 1; 13254 public static final int DUMP_RESOLVERS = 1 << 2; 13255 public static final int DUMP_PERMISSIONS = 1 << 3; 13256 public static final int DUMP_PACKAGES = 1 << 4; 13257 public static final int DUMP_SHARED_USERS = 1 << 5; 13258 public static final int DUMP_MESSAGES = 1 << 6; 13259 public static final int DUMP_PROVIDERS = 1 << 7; 13260 public static final int DUMP_VERIFIERS = 1 << 8; 13261 public static final int DUMP_PREFERRED = 1 << 9; 13262 public static final int DUMP_PREFERRED_XML = 1 << 10; 13263 public static final int DUMP_KEYSETS = 1 << 11; 13264 public static final int DUMP_VERSION = 1 << 12; 13265 public static final int DUMP_INSTALLS = 1 << 13; 13266 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14; 13267 public static final int DUMP_DOMAIN_PREFERRED = 1 << 15; 13268 13269 public static final int OPTION_SHOW_FILTERS = 1 << 0; 13270 13271 private int mTypes; 13272 13273 private int mOptions; 13274 13275 private boolean mTitlePrinted; 13276 13277 private SharedUserSetting mSharedUser; 13278 13279 public boolean isDumping(int type) { 13280 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 13281 return true; 13282 } 13283 13284 return (mTypes & type) != 0; 13285 } 13286 13287 public void setDump(int type) { 13288 mTypes |= type; 13289 } 13290 13291 public boolean isOptionEnabled(int option) { 13292 return (mOptions & option) != 0; 13293 } 13294 13295 public void setOptionEnabled(int option) { 13296 mOptions |= option; 13297 } 13298 13299 public boolean onTitlePrinted() { 13300 final boolean printed = mTitlePrinted; 13301 mTitlePrinted = true; 13302 return printed; 13303 } 13304 13305 public boolean getTitlePrinted() { 13306 return mTitlePrinted; 13307 } 13308 13309 public void setTitlePrinted(boolean enabled) { 13310 mTitlePrinted = enabled; 13311 } 13312 13313 public SharedUserSetting getSharedUser() { 13314 return mSharedUser; 13315 } 13316 13317 public void setSharedUser(SharedUserSetting user) { 13318 mSharedUser = user; 13319 } 13320 } 13321 13322 @Override 13323 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 13324 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 13325 != PackageManager.PERMISSION_GRANTED) { 13326 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 13327 + Binder.getCallingPid() 13328 + ", uid=" + Binder.getCallingUid() 13329 + " without permission " 13330 + android.Manifest.permission.DUMP); 13331 return; 13332 } 13333 13334 DumpState dumpState = new DumpState(); 13335 boolean fullPreferred = false; 13336 boolean checkin = false; 13337 13338 String packageName = null; 13339 13340 int opti = 0; 13341 while (opti < args.length) { 13342 String opt = args[opti]; 13343 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13344 break; 13345 } 13346 opti++; 13347 13348 if ("-a".equals(opt)) { 13349 // Right now we only know how to print all. 13350 } else if ("-h".equals(opt)) { 13351 pw.println("Package manager dump options:"); 13352 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 13353 pw.println(" --checkin: dump for a checkin"); 13354 pw.println(" -f: print details of intent filters"); 13355 pw.println(" -h: print this help"); 13356 pw.println(" cmd may be one of:"); 13357 pw.println(" l[ibraries]: list known shared libraries"); 13358 pw.println(" f[ibraries]: list device features"); 13359 pw.println(" k[eysets]: print known keysets"); 13360 pw.println(" r[esolvers]: dump intent resolvers"); 13361 pw.println(" perm[issions]: dump permissions"); 13362 pw.println(" pref[erred]: print preferred package settings"); 13363 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 13364 pw.println(" prov[iders]: dump content providers"); 13365 pw.println(" p[ackages]: dump installed packages"); 13366 pw.println(" s[hared-users]: dump shared user IDs"); 13367 pw.println(" m[essages]: print collected runtime messages"); 13368 pw.println(" v[erifiers]: print package verifier info"); 13369 pw.println(" version: print database version info"); 13370 pw.println(" write: write current settings now"); 13371 pw.println(" <package.name>: info about given package"); 13372 pw.println(" installs: details about install sessions"); 13373 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 13374 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 13375 return; 13376 } else if ("--checkin".equals(opt)) { 13377 checkin = true; 13378 } else if ("-f".equals(opt)) { 13379 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13380 } else { 13381 pw.println("Unknown argument: " + opt + "; use -h for help"); 13382 } 13383 } 13384 13385 // Is the caller requesting to dump a particular piece of data? 13386 if (opti < args.length) { 13387 String cmd = args[opti]; 13388 opti++; 13389 // Is this a package name? 13390 if ("android".equals(cmd) || cmd.contains(".")) { 13391 packageName = cmd; 13392 // When dumping a single package, we always dump all of its 13393 // filter information since the amount of data will be reasonable. 13394 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13395 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 13396 dumpState.setDump(DumpState.DUMP_LIBS); 13397 } else if ("f".equals(cmd) || "features".equals(cmd)) { 13398 dumpState.setDump(DumpState.DUMP_FEATURES); 13399 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 13400 dumpState.setDump(DumpState.DUMP_RESOLVERS); 13401 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 13402 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 13403 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 13404 dumpState.setDump(DumpState.DUMP_PREFERRED); 13405 } else if ("preferred-xml".equals(cmd)) { 13406 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 13407 if (opti < args.length && "--full".equals(args[opti])) { 13408 fullPreferred = true; 13409 opti++; 13410 } 13411 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 13412 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 13413 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 13414 dumpState.setDump(DumpState.DUMP_PACKAGES); 13415 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 13416 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 13417 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 13418 dumpState.setDump(DumpState.DUMP_PROVIDERS); 13419 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 13420 dumpState.setDump(DumpState.DUMP_MESSAGES); 13421 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 13422 dumpState.setDump(DumpState.DUMP_VERIFIERS); 13423 } else if ("i".equals(cmd) || "ifv".equals(cmd) 13424 || "intent-filter-verifiers".equals(cmd)) { 13425 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 13426 } else if ("version".equals(cmd)) { 13427 dumpState.setDump(DumpState.DUMP_VERSION); 13428 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 13429 dumpState.setDump(DumpState.DUMP_KEYSETS); 13430 } else if ("installs".equals(cmd)) { 13431 dumpState.setDump(DumpState.DUMP_INSTALLS); 13432 } else if ("write".equals(cmd)) { 13433 synchronized (mPackages) { 13434 mSettings.writeLPr(); 13435 pw.println("Settings written."); 13436 return; 13437 } 13438 } 13439 } 13440 13441 if (checkin) { 13442 pw.println("vers,1"); 13443 } 13444 13445 // reader 13446 synchronized (mPackages) { 13447 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 13448 if (!checkin) { 13449 if (dumpState.onTitlePrinted()) 13450 pw.println(); 13451 pw.println("Database versions:"); 13452 pw.print(" SDK Version:"); 13453 pw.print(" internal="); 13454 pw.print(mSettings.mInternalSdkPlatform); 13455 pw.print(" external="); 13456 pw.println(mSettings.mExternalSdkPlatform); 13457 pw.print(" DB Version:"); 13458 pw.print(" internal="); 13459 pw.print(mSettings.mInternalDatabaseVersion); 13460 pw.print(" external="); 13461 pw.println(mSettings.mExternalDatabaseVersion); 13462 } 13463 } 13464 13465 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 13466 if (!checkin) { 13467 if (dumpState.onTitlePrinted()) 13468 pw.println(); 13469 pw.println("Verifiers:"); 13470 pw.print(" Required: "); 13471 pw.print(mRequiredVerifierPackage); 13472 pw.print(" (uid="); 13473 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 13474 pw.println(")"); 13475 } else if (mRequiredVerifierPackage != null) { 13476 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 13477 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 13478 } 13479 } 13480 13481 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 13482 packageName == null) { 13483 if (mIntentFilterVerifierComponent != null) { 13484 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 13485 if (!checkin) { 13486 if (dumpState.onTitlePrinted()) 13487 pw.println(); 13488 pw.println("Intent Filter Verifier:"); 13489 pw.print(" Using: "); 13490 pw.print(verifierPackageName); 13491 pw.print(" (uid="); 13492 pw.print(getPackageUid(verifierPackageName, 0)); 13493 pw.println(")"); 13494 } else if (verifierPackageName != null) { 13495 pw.print("ifv,"); pw.print(verifierPackageName); 13496 pw.print(","); pw.println(getPackageUid(verifierPackageName, 0)); 13497 } 13498 } else { 13499 pw.println(); 13500 pw.println("No Intent Filter Verifier available!"); 13501 } 13502 } 13503 13504 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 13505 boolean printedHeader = false; 13506 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 13507 while (it.hasNext()) { 13508 String name = it.next(); 13509 SharedLibraryEntry ent = mSharedLibraries.get(name); 13510 if (!checkin) { 13511 if (!printedHeader) { 13512 if (dumpState.onTitlePrinted()) 13513 pw.println(); 13514 pw.println("Libraries:"); 13515 printedHeader = true; 13516 } 13517 pw.print(" "); 13518 } else { 13519 pw.print("lib,"); 13520 } 13521 pw.print(name); 13522 if (!checkin) { 13523 pw.print(" -> "); 13524 } 13525 if (ent.path != null) { 13526 if (!checkin) { 13527 pw.print("(jar) "); 13528 pw.print(ent.path); 13529 } else { 13530 pw.print(",jar,"); 13531 pw.print(ent.path); 13532 } 13533 } else { 13534 if (!checkin) { 13535 pw.print("(apk) "); 13536 pw.print(ent.apk); 13537 } else { 13538 pw.print(",apk,"); 13539 pw.print(ent.apk); 13540 } 13541 } 13542 pw.println(); 13543 } 13544 } 13545 13546 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 13547 if (dumpState.onTitlePrinted()) 13548 pw.println(); 13549 if (!checkin) { 13550 pw.println("Features:"); 13551 } 13552 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 13553 while (it.hasNext()) { 13554 String name = it.next(); 13555 if (!checkin) { 13556 pw.print(" "); 13557 } else { 13558 pw.print("feat,"); 13559 } 13560 pw.println(name); 13561 } 13562 } 13563 13564 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 13565 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 13566 : "Activity Resolver Table:", " ", packageName, 13567 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13568 dumpState.setTitlePrinted(true); 13569 } 13570 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 13571 : "Receiver Resolver Table:", " ", packageName, 13572 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13573 dumpState.setTitlePrinted(true); 13574 } 13575 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 13576 : "Service Resolver Table:", " ", packageName, 13577 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13578 dumpState.setTitlePrinted(true); 13579 } 13580 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 13581 : "Provider Resolver Table:", " ", packageName, 13582 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13583 dumpState.setTitlePrinted(true); 13584 } 13585 } 13586 13587 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 13588 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13589 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13590 int user = mSettings.mPreferredActivities.keyAt(i); 13591 if (pir.dump(pw, 13592 dumpState.getTitlePrinted() 13593 ? "\nPreferred Activities User " + user + ":" 13594 : "Preferred Activities User " + user + ":", " ", 13595 packageName, true, false)) { 13596 dumpState.setTitlePrinted(true); 13597 } 13598 } 13599 } 13600 13601 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 13602 pw.flush(); 13603 FileOutputStream fout = new FileOutputStream(fd); 13604 BufferedOutputStream str = new BufferedOutputStream(fout); 13605 XmlSerializer serializer = new FastXmlSerializer(); 13606 try { 13607 serializer.setOutput(str, "utf-8"); 13608 serializer.startDocument(null, true); 13609 serializer.setFeature( 13610 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 13611 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 13612 serializer.endDocument(); 13613 serializer.flush(); 13614 } catch (IllegalArgumentException e) { 13615 pw.println("Failed writing: " + e); 13616 } catch (IllegalStateException e) { 13617 pw.println("Failed writing: " + e); 13618 } catch (IOException e) { 13619 pw.println("Failed writing: " + e); 13620 } 13621 } 13622 13623 if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) { 13624 pw.println(); 13625 int count = mSettings.mPackages.size(); 13626 if (count == 0) { 13627 pw.println("No domain preferred apps!"); 13628 pw.println(); 13629 } else { 13630 final String prefix = " "; 13631 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 13632 if (allPackageSettings.size() == 0) { 13633 pw.println("No domain preferred apps!"); 13634 pw.println(); 13635 } else { 13636 pw.println("Domain preferred apps status:"); 13637 pw.println(); 13638 count = 0; 13639 for (PackageSetting ps : allPackageSettings) { 13640 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 13641 if (ivi == null || ivi.getPackageName() == null) continue; 13642 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 13643 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 13644 pw.println(prefix + "Status: " + ivi.getStatusString()); 13645 pw.println(); 13646 count++; 13647 } 13648 if (count == 0) { 13649 pw.println(prefix + "No domain preferred app status!"); 13650 pw.println(); 13651 } 13652 for (int userId : sUserManager.getUserIds()) { 13653 pw.println("Domain preferred apps for User " + userId + ":"); 13654 pw.println(); 13655 count = 0; 13656 for (PackageSetting ps : allPackageSettings) { 13657 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 13658 if (ivi == null || ivi.getPackageName() == null) { 13659 continue; 13660 } 13661 final int status = ps.getDomainVerificationStatusForUser(userId); 13662 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 13663 continue; 13664 } 13665 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 13666 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 13667 String statusStr = IntentFilterVerificationInfo. 13668 getStatusStringFromValue(status); 13669 pw.println(prefix + "Status: " + statusStr); 13670 pw.println(); 13671 count++; 13672 } 13673 if (count == 0) { 13674 pw.println(prefix + "No domain preferred apps!"); 13675 pw.println(); 13676 } 13677 } 13678 } 13679 } 13680 } 13681 13682 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 13683 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 13684 if (packageName == null) { 13685 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 13686 if (iperm == 0) { 13687 if (dumpState.onTitlePrinted()) 13688 pw.println(); 13689 pw.println("AppOp Permissions:"); 13690 } 13691 pw.print(" AppOp Permission "); 13692 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 13693 pw.println(":"); 13694 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 13695 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 13696 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 13697 } 13698 } 13699 } 13700 } 13701 13702 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 13703 boolean printedSomething = false; 13704 for (PackageParser.Provider p : mProviders.mProviders.values()) { 13705 if (packageName != null && !packageName.equals(p.info.packageName)) { 13706 continue; 13707 } 13708 if (!printedSomething) { 13709 if (dumpState.onTitlePrinted()) 13710 pw.println(); 13711 pw.println("Registered ContentProviders:"); 13712 printedSomething = true; 13713 } 13714 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 13715 pw.print(" "); pw.println(p.toString()); 13716 } 13717 printedSomething = false; 13718 for (Map.Entry<String, PackageParser.Provider> entry : 13719 mProvidersByAuthority.entrySet()) { 13720 PackageParser.Provider p = entry.getValue(); 13721 if (packageName != null && !packageName.equals(p.info.packageName)) { 13722 continue; 13723 } 13724 if (!printedSomething) { 13725 if (dumpState.onTitlePrinted()) 13726 pw.println(); 13727 pw.println("ContentProvider Authorities:"); 13728 printedSomething = true; 13729 } 13730 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 13731 pw.print(" "); pw.println(p.toString()); 13732 if (p.info != null && p.info.applicationInfo != null) { 13733 final String appInfo = p.info.applicationInfo.toString(); 13734 pw.print(" applicationInfo="); pw.println(appInfo); 13735 } 13736 } 13737 } 13738 13739 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 13740 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 13741 } 13742 13743 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 13744 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 13745 } 13746 13747 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 13748 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin); 13749 } 13750 13751 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 13752 // XXX should handle packageName != null by dumping only install data that 13753 // the given package is involved with. 13754 if (dumpState.onTitlePrinted()) pw.println(); 13755 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 13756 } 13757 13758 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 13759 if (dumpState.onTitlePrinted()) pw.println(); 13760 mSettings.dumpReadMessagesLPr(pw, dumpState); 13761 13762 pw.println(); 13763 pw.println("Package warning messages:"); 13764 BufferedReader in = null; 13765 String line = null; 13766 try { 13767 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 13768 while ((line = in.readLine()) != null) { 13769 if (line.contains("ignored: updated version")) continue; 13770 pw.println(line); 13771 } 13772 } catch (IOException ignored) { 13773 } finally { 13774 IoUtils.closeQuietly(in); 13775 } 13776 } 13777 13778 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 13779 BufferedReader in = null; 13780 String line = null; 13781 try { 13782 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 13783 while ((line = in.readLine()) != null) { 13784 if (line.contains("ignored: updated version")) continue; 13785 pw.print("msg,"); 13786 pw.println(line); 13787 } 13788 } catch (IOException ignored) { 13789 } finally { 13790 IoUtils.closeQuietly(in); 13791 } 13792 } 13793 } 13794 } 13795 13796 // ------- apps on sdcard specific code ------- 13797 static final boolean DEBUG_SD_INSTALL = false; 13798 13799 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 13800 13801 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 13802 13803 private boolean mMediaMounted = false; 13804 13805 static String getEncryptKey() { 13806 try { 13807 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 13808 SD_ENCRYPTION_KEYSTORE_NAME); 13809 if (sdEncKey == null) { 13810 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 13811 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 13812 if (sdEncKey == null) { 13813 Slog.e(TAG, "Failed to create encryption keys"); 13814 return null; 13815 } 13816 } 13817 return sdEncKey; 13818 } catch (NoSuchAlgorithmException nsae) { 13819 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 13820 return null; 13821 } catch (IOException ioe) { 13822 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 13823 return null; 13824 } 13825 } 13826 13827 /* 13828 * Update media status on PackageManager. 13829 */ 13830 @Override 13831 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 13832 int callingUid = Binder.getCallingUid(); 13833 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13834 throw new SecurityException("Media status can only be updated by the system"); 13835 } 13836 // reader; this apparently protects mMediaMounted, but should probably 13837 // be a different lock in that case. 13838 synchronized (mPackages) { 13839 Log.i(TAG, "Updating external media status from " 13840 + (mMediaMounted ? "mounted" : "unmounted") + " to " 13841 + (mediaStatus ? "mounted" : "unmounted")); 13842 if (DEBUG_SD_INSTALL) 13843 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 13844 + ", mMediaMounted=" + mMediaMounted); 13845 if (mediaStatus == mMediaMounted) { 13846 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 13847 : 0, -1); 13848 mHandler.sendMessage(msg); 13849 return; 13850 } 13851 mMediaMounted = mediaStatus; 13852 } 13853 // Queue up an async operation since the package installation may take a 13854 // little while. 13855 mHandler.post(new Runnable() { 13856 public void run() { 13857 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 13858 } 13859 }); 13860 } 13861 13862 /** 13863 * Called by MountService when the initial ASECs to scan are available. 13864 * Should block until all the ASEC containers are finished being scanned. 13865 */ 13866 public void scanAvailableAsecs() { 13867 updateExternalMediaStatusInner(true, false, false); 13868 if (mShouldRestoreconData) { 13869 SELinuxMMAC.setRestoreconDone(); 13870 mShouldRestoreconData = false; 13871 } 13872 } 13873 13874 /* 13875 * Collect information of applications on external media, map them against 13876 * existing containers and update information based on current mount status. 13877 * Please note that we always have to report status if reportStatus has been 13878 * set to true especially when unloading packages. 13879 */ 13880 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 13881 boolean externalStorage) { 13882 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 13883 int[] uidArr = EmptyArray.INT; 13884 13885 final String[] list = PackageHelper.getSecureContainerList(); 13886 if (ArrayUtils.isEmpty(list)) { 13887 Log.i(TAG, "No secure containers found"); 13888 } else { 13889 // Process list of secure containers and categorize them 13890 // as active or stale based on their package internal state. 13891 13892 // reader 13893 synchronized (mPackages) { 13894 for (String cid : list) { 13895 // Leave stages untouched for now; installer service owns them 13896 if (PackageInstallerService.isStageName(cid)) continue; 13897 13898 if (DEBUG_SD_INSTALL) 13899 Log.i(TAG, "Processing container " + cid); 13900 String pkgName = getAsecPackageName(cid); 13901 if (pkgName == null) { 13902 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 13903 continue; 13904 } 13905 if (DEBUG_SD_INSTALL) 13906 Log.i(TAG, "Looking for pkg : " + pkgName); 13907 13908 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13909 if (ps == null) { 13910 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 13911 continue; 13912 } 13913 13914 /* 13915 * Skip packages that are not external if we're unmounting 13916 * external storage. 13917 */ 13918 if (externalStorage && !isMounted && !isExternal(ps)) { 13919 continue; 13920 } 13921 13922 final AsecInstallArgs args = new AsecInstallArgs(cid, 13923 getAppDexInstructionSets(ps), ps.isForwardLocked()); 13924 // The package status is changed only if the code path 13925 // matches between settings and the container id. 13926 if (ps.codePathString != null 13927 && ps.codePathString.startsWith(args.getCodePath())) { 13928 if (DEBUG_SD_INSTALL) { 13929 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 13930 + " at code path: " + ps.codePathString); 13931 } 13932 13933 // We do have a valid package installed on sdcard 13934 processCids.put(args, ps.codePathString); 13935 final int uid = ps.appId; 13936 if (uid != -1) { 13937 uidArr = ArrayUtils.appendInt(uidArr, uid); 13938 } 13939 } else { 13940 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 13941 + ps.codePathString); 13942 } 13943 } 13944 } 13945 13946 Arrays.sort(uidArr); 13947 } 13948 13949 // Process packages with valid entries. 13950 if (isMounted) { 13951 if (DEBUG_SD_INSTALL) 13952 Log.i(TAG, "Loading packages"); 13953 loadMediaPackages(processCids, uidArr); 13954 startCleaningPackages(); 13955 mInstallerService.onSecureContainersAvailable(); 13956 } else { 13957 if (DEBUG_SD_INSTALL) 13958 Log.i(TAG, "Unloading packages"); 13959 unloadMediaPackages(processCids, uidArr, reportStatus); 13960 } 13961 } 13962 13963 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 13964 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 13965 final int size = infos.size(); 13966 final String[] packageNames = new String[size]; 13967 final int[] packageUids = new int[size]; 13968 for (int i = 0; i < size; i++) { 13969 final ApplicationInfo info = infos.get(i); 13970 packageNames[i] = info.packageName; 13971 packageUids[i] = info.uid; 13972 } 13973 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 13974 finishedReceiver); 13975 } 13976 13977 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 13978 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 13979 sendResourcesChangedBroadcast(mediaStatus, replacing, 13980 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 13981 } 13982 13983 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 13984 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 13985 int size = pkgList.length; 13986 if (size > 0) { 13987 // Send broadcasts here 13988 Bundle extras = new Bundle(); 13989 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 13990 if (uidArr != null) { 13991 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 13992 } 13993 if (replacing) { 13994 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 13995 } 13996 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 13997 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 13998 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 13999 } 14000 } 14001 14002 /* 14003 * Look at potentially valid container ids from processCids If package 14004 * information doesn't match the one on record or package scanning fails, 14005 * the cid is added to list of removeCids. We currently don't delete stale 14006 * containers. 14007 */ 14008 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) { 14009 ArrayList<String> pkgList = new ArrayList<String>(); 14010 Set<AsecInstallArgs> keys = processCids.keySet(); 14011 14012 for (AsecInstallArgs args : keys) { 14013 String codePath = processCids.get(args); 14014 if (DEBUG_SD_INSTALL) 14015 Log.i(TAG, "Loading container : " + args.cid); 14016 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14017 try { 14018 // Make sure there are no container errors first. 14019 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 14020 Slog.e(TAG, "Failed to mount cid : " + args.cid 14021 + " when installing from sdcard"); 14022 continue; 14023 } 14024 // Check code path here. 14025 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 14026 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 14027 + " does not match one in settings " + codePath); 14028 continue; 14029 } 14030 // Parse package 14031 int parseFlags = mDefParseFlags; 14032 if (args.isExternalAsec()) { 14033 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 14034 } 14035 if (args.isFwdLocked()) { 14036 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 14037 } 14038 14039 synchronized (mInstallLock) { 14040 PackageParser.Package pkg = null; 14041 try { 14042 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null); 14043 } catch (PackageManagerException e) { 14044 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 14045 } 14046 // Scan the package 14047 if (pkg != null) { 14048 /* 14049 * TODO why is the lock being held? doPostInstall is 14050 * called in other places without the lock. This needs 14051 * to be straightened out. 14052 */ 14053 // writer 14054 synchronized (mPackages) { 14055 retCode = PackageManager.INSTALL_SUCCEEDED; 14056 pkgList.add(pkg.packageName); 14057 // Post process args 14058 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 14059 pkg.applicationInfo.uid); 14060 } 14061 } else { 14062 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 14063 } 14064 } 14065 14066 } finally { 14067 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 14068 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 14069 } 14070 } 14071 } 14072 // writer 14073 synchronized (mPackages) { 14074 // If the platform SDK has changed since the last time we booted, 14075 // we need to re-grant app permission to catch any new ones that 14076 // appear. This is really a hack, and means that apps can in some 14077 // cases get permissions that the user didn't initially explicitly 14078 // allow... it would be nice to have some better way to handle 14079 // this situation. 14080 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 14081 if (regrantPermissions) 14082 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 14083 + mSdkVersion + "; regranting permissions for external storage"); 14084 mSettings.mExternalSdkPlatform = mSdkVersion; 14085 14086 // Make sure group IDs have been assigned, and any permission 14087 // changes in other apps are accounted for 14088 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 14089 | (regrantPermissions 14090 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 14091 : 0)); 14092 14093 mSettings.updateExternalDatabaseVersion(); 14094 14095 // can downgrade to reader 14096 // Persist settings 14097 mSettings.writeLPr(); 14098 } 14099 // Send a broadcast to let everyone know we are done processing 14100 if (pkgList.size() > 0) { 14101 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 14102 } 14103 } 14104 14105 /* 14106 * Utility method to unload a list of specified containers 14107 */ 14108 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 14109 // Just unmount all valid containers. 14110 for (AsecInstallArgs arg : cidArgs) { 14111 synchronized (mInstallLock) { 14112 arg.doPostDeleteLI(false); 14113 } 14114 } 14115 } 14116 14117 /* 14118 * Unload packages mounted on external media. This involves deleting package 14119 * data from internal structures, sending broadcasts about diabled packages, 14120 * gc'ing to free up references, unmounting all secure containers 14121 * corresponding to packages on external media, and posting a 14122 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 14123 * that we always have to post this message if status has been requested no 14124 * matter what. 14125 */ 14126 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 14127 final boolean reportStatus) { 14128 if (DEBUG_SD_INSTALL) 14129 Log.i(TAG, "unloading media packages"); 14130 ArrayList<String> pkgList = new ArrayList<String>(); 14131 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 14132 final Set<AsecInstallArgs> keys = processCids.keySet(); 14133 for (AsecInstallArgs args : keys) { 14134 String pkgName = args.getPackageName(); 14135 if (DEBUG_SD_INSTALL) 14136 Log.i(TAG, "Trying to unload pkg : " + pkgName); 14137 // Delete package internally 14138 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14139 synchronized (mInstallLock) { 14140 boolean res = deletePackageLI(pkgName, null, false, null, null, 14141 PackageManager.DELETE_KEEP_DATA, outInfo, false); 14142 if (res) { 14143 pkgList.add(pkgName); 14144 } else { 14145 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 14146 failedList.add(args); 14147 } 14148 } 14149 } 14150 14151 // reader 14152 synchronized (mPackages) { 14153 // We didn't update the settings after removing each package; 14154 // write them now for all packages. 14155 mSettings.writeLPr(); 14156 } 14157 14158 // We have to absolutely send UPDATED_MEDIA_STATUS only 14159 // after confirming that all the receivers processed the ordered 14160 // broadcast when packages get disabled, force a gc to clean things up. 14161 // and unload all the containers. 14162 if (pkgList.size() > 0) { 14163 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 14164 new IIntentReceiver.Stub() { 14165 public void performReceive(Intent intent, int resultCode, String data, 14166 Bundle extras, boolean ordered, boolean sticky, 14167 int sendingUser) throws RemoteException { 14168 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 14169 reportStatus ? 1 : 0, 1, keys); 14170 mHandler.sendMessage(msg); 14171 } 14172 }); 14173 } else { 14174 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 14175 keys); 14176 mHandler.sendMessage(msg); 14177 } 14178 } 14179 14180 private void loadPrivatePackages(VolumeInfo vol) { 14181 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 14182 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 14183 synchronized (mPackages) { 14184 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14185 for (PackageSetting ps : packages) { 14186 synchronized (mInstallLock) { 14187 final PackageParser.Package pkg; 14188 try { 14189 pkg = scanPackageLI(ps.codePath, parseFlags, 0, 0, null); 14190 loaded.add(pkg.applicationInfo); 14191 } catch (PackageManagerException e) { 14192 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 14193 } 14194 } 14195 } 14196 14197 // TODO: regrant any permissions that changed based since original install 14198 14199 mSettings.writeLPr(); 14200 } 14201 14202 Slog.d(TAG, "Loaded packages " + loaded); 14203 sendResourcesChangedBroadcast(true, false, loaded, null); 14204 } 14205 14206 private void unloadPrivatePackages(VolumeInfo vol) { 14207 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 14208 synchronized (mPackages) { 14209 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14210 for (PackageSetting ps : packages) { 14211 if (ps.pkg == null) continue; 14212 synchronized (mInstallLock) { 14213 final ApplicationInfo info = ps.pkg.applicationInfo; 14214 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14215 if (deletePackageLI(ps.name, null, false, null, null, 14216 PackageManager.DELETE_KEEP_DATA, outInfo, false)) { 14217 unloaded.add(info); 14218 } else { 14219 Slog.w(TAG, "Failed to unload " + ps.codePath); 14220 } 14221 } 14222 } 14223 14224 mSettings.writeLPr(); 14225 } 14226 14227 Slog.d(TAG, "Unloaded packages " + unloaded); 14228 sendResourcesChangedBroadcast(false, false, unloaded, null); 14229 } 14230 14231 private void unfreezePackage(String packageName) { 14232 synchronized (mPackages) { 14233 final PackageSetting ps = mSettings.mPackages.get(packageName); 14234 if (ps != null) { 14235 ps.frozen = false; 14236 } 14237 } 14238 } 14239 14240 @Override 14241 public int movePackage(final String packageName, final String volumeUuid) { 14242 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14243 14244 final int moveId = mNextMoveId.getAndIncrement(); 14245 try { 14246 movePackageInternal(packageName, volumeUuid, moveId); 14247 } catch (PackageManagerException e) { 14248 Slog.d(TAG, "Failed to move " + packageName, e); 14249 mMoveCallbacks.notifyStatusChanged(moveId, 14250 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 14251 } 14252 return moveId; 14253 } 14254 14255 private void movePackageInternal(final String packageName, final String volumeUuid, 14256 final int moveId) throws PackageManagerException { 14257 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 14258 final PackageManager pm = mContext.getPackageManager(); 14259 14260 final boolean currentAsec; 14261 final String currentVolumeUuid; 14262 final File codeFile; 14263 final String installerPackageName; 14264 final String packageAbiOverride; 14265 final int appId; 14266 final String seinfo; 14267 final String label; 14268 14269 // reader 14270 synchronized (mPackages) { 14271 final PackageParser.Package pkg = mPackages.get(packageName); 14272 final PackageSetting ps = mSettings.mPackages.get(packageName); 14273 if (pkg == null || ps == null) { 14274 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 14275 } 14276 14277 if (pkg.applicationInfo.isSystemApp()) { 14278 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 14279 "Cannot move system application"); 14280 } 14281 14282 if (Objects.equals(ps.volumeUuid, volumeUuid)) { 14283 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14284 "Package already moved to " + volumeUuid); 14285 } 14286 14287 if (ps.frozen) { 14288 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 14289 "Failed to move already frozen package"); 14290 } 14291 14292 ps.frozen = true; 14293 14294 currentAsec = pkg.applicationInfo.isForwardLocked() 14295 || pkg.applicationInfo.isExternalAsec(); 14296 currentVolumeUuid = ps.volumeUuid; 14297 codeFile = new File(pkg.codePath); 14298 installerPackageName = ps.installerPackageName; 14299 packageAbiOverride = ps.cpuAbiOverrideString; 14300 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 14301 seinfo = pkg.applicationInfo.seinfo; 14302 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 14303 } 14304 14305 // Now that we're guarded by frozen state, kill app during upgrade 14306 killApplication(packageName, appId, "move pkg"); 14307 14308 final Bundle extras = new Bundle(); 14309 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 14310 extras.putString(Intent.EXTRA_TITLE, label); 14311 mMoveCallbacks.notifyCreated(moveId, extras); 14312 14313 int installFlags; 14314 final boolean moveData; 14315 14316 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 14317 installFlags = INSTALL_INTERNAL; 14318 moveData = !currentAsec; 14319 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 14320 installFlags = INSTALL_EXTERNAL; 14321 moveData = false; 14322 } else { 14323 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14324 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 14325 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 14326 || !volume.isMountedWritable()) { 14327 unfreezePackage(packageName); 14328 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14329 "Move location not mounted private volume"); 14330 } 14331 14332 Preconditions.checkState(!currentAsec); 14333 14334 installFlags = INSTALL_INTERNAL; 14335 moveData = true; 14336 } 14337 14338 Slog.d(TAG, "Moving " + packageName + " from " + currentVolumeUuid + " to " + volumeUuid); 14339 mMoveCallbacks.notifyStatusChanged(moveId, 10); 14340 14341 if (moveData) { 14342 synchronized (mInstallLock) { 14343 // TODO: split this into separate copy and delete operations 14344 if (mInstaller.moveUserDataDirs(currentVolumeUuid, volumeUuid, packageName, appId, 14345 seinfo) != 0) { 14346 unfreezePackage(packageName); 14347 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14348 "Failed to move private data to " + volumeUuid); 14349 } 14350 } 14351 } 14352 14353 mMoveCallbacks.notifyStatusChanged(moveId, 50); 14354 14355 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 14356 @Override 14357 public void onUserActionRequired(Intent intent) throws RemoteException { 14358 throw new IllegalStateException(); 14359 } 14360 14361 @Override 14362 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 14363 Bundle extras) throws RemoteException { 14364 Slog.d(TAG, "Install result for move: " 14365 + PackageManager.installStatusToString(returnCode, msg)); 14366 14367 // Regardless of success or failure of the move operation, 14368 // always unfreeze the package 14369 unfreezePackage(packageName); 14370 14371 final int status = PackageManager.installStatusToPublicStatus(returnCode); 14372 switch (status) { 14373 case PackageInstaller.STATUS_SUCCESS: 14374 mMoveCallbacks.notifyStatusChanged(moveId, 14375 PackageManager.MOVE_SUCCEEDED); 14376 break; 14377 case PackageInstaller.STATUS_FAILURE_STORAGE: 14378 mMoveCallbacks.notifyStatusChanged(moveId, 14379 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 14380 break; 14381 default: 14382 mMoveCallbacks.notifyStatusChanged(moveId, 14383 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 14384 break; 14385 } 14386 } 14387 }; 14388 14389 // Treat a move like reinstalling an existing app, which ensures that we 14390 // process everythign uniformly, like unpacking native libraries. 14391 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 14392 14393 final Message msg = mHandler.obtainMessage(INIT_COPY); 14394 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 14395 msg.obj = new InstallParams(origin, installObserver, installFlags, 14396 installerPackageName, volumeUuid, null, user, packageAbiOverride); 14397 mHandler.sendMessage(msg); 14398 } 14399 14400 @Override 14401 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 14402 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14403 14404 final int realMoveId = mNextMoveId.getAndIncrement(); 14405 final Bundle extras = new Bundle(); 14406 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 14407 mMoveCallbacks.notifyCreated(realMoveId, extras); 14408 14409 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 14410 @Override 14411 public void onCreated(int moveId, Bundle extras) { 14412 // Ignored 14413 } 14414 14415 @Override 14416 public void onStatusChanged(int moveId, int status, long estMillis) { 14417 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 14418 } 14419 }; 14420 14421 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14422 storage.setPrimaryStorageUuid(volumeUuid, callback); 14423 return realMoveId; 14424 } 14425 14426 @Override 14427 public int getMoveStatus(int moveId) { 14428 mContext.enforceCallingOrSelfPermission( 14429 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14430 return mMoveCallbacks.mLastStatus.get(moveId); 14431 } 14432 14433 @Override 14434 public void registerMoveCallback(IPackageMoveObserver callback) { 14435 mContext.enforceCallingOrSelfPermission( 14436 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14437 mMoveCallbacks.register(callback); 14438 } 14439 14440 @Override 14441 public void unregisterMoveCallback(IPackageMoveObserver callback) { 14442 mContext.enforceCallingOrSelfPermission( 14443 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14444 mMoveCallbacks.unregister(callback); 14445 } 14446 14447 @Override 14448 public boolean setInstallLocation(int loc) { 14449 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 14450 null); 14451 if (getInstallLocation() == loc) { 14452 return true; 14453 } 14454 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 14455 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 14456 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 14457 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 14458 return true; 14459 } 14460 return false; 14461 } 14462 14463 @Override 14464 public int getInstallLocation() { 14465 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 14466 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 14467 PackageHelper.APP_INSTALL_AUTO); 14468 } 14469 14470 /** Called by UserManagerService */ 14471 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 14472 mDirtyUsers.remove(userHandle); 14473 mSettings.removeUserLPw(userHandle); 14474 mPendingBroadcasts.remove(userHandle); 14475 if (mInstaller != null) { 14476 // Technically, we shouldn't be doing this with the package lock 14477 // held. However, this is very rare, and there is already so much 14478 // other disk I/O going on, that we'll let it slide for now. 14479 final StorageManager storage = StorageManager.from(mContext); 14480 final List<VolumeInfo> vols = storage.getVolumes(); 14481 for (VolumeInfo vol : vols) { 14482 if (vol.getType() == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) { 14483 final String volumeUuid = vol.getFsUuid(); 14484 Slog.d(TAG, "Removing user data on volume " + volumeUuid); 14485 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 14486 } 14487 } 14488 } 14489 mUserNeedsBadging.delete(userHandle); 14490 removeUnusedPackagesLILPw(userManager, userHandle); 14491 } 14492 14493 /** 14494 * We're removing userHandle and would like to remove any downloaded packages 14495 * that are no longer in use by any other user. 14496 * @param userHandle the user being removed 14497 */ 14498 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 14499 final boolean DEBUG_CLEAN_APKS = false; 14500 int [] users = userManager.getUserIdsLPr(); 14501 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 14502 while (psit.hasNext()) { 14503 PackageSetting ps = psit.next(); 14504 if (ps.pkg == null) { 14505 continue; 14506 } 14507 final String packageName = ps.pkg.packageName; 14508 // Skip over if system app 14509 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14510 continue; 14511 } 14512 if (DEBUG_CLEAN_APKS) { 14513 Slog.i(TAG, "Checking package " + packageName); 14514 } 14515 boolean keep = false; 14516 for (int i = 0; i < users.length; i++) { 14517 if (users[i] != userHandle && ps.getInstalled(users[i])) { 14518 keep = true; 14519 if (DEBUG_CLEAN_APKS) { 14520 Slog.i(TAG, " Keeping package " + packageName + " for user " 14521 + users[i]); 14522 } 14523 break; 14524 } 14525 } 14526 if (!keep) { 14527 if (DEBUG_CLEAN_APKS) { 14528 Slog.i(TAG, " Removing package " + packageName); 14529 } 14530 mHandler.post(new Runnable() { 14531 public void run() { 14532 deletePackageX(packageName, userHandle, 0); 14533 } //end run 14534 }); 14535 } 14536 } 14537 } 14538 14539 /** Called by UserManagerService */ 14540 void createNewUserLILPw(int userHandle, File path) { 14541 if (mInstaller != null) { 14542 mInstaller.createUserConfig(userHandle); 14543 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 14544 } 14545 } 14546 14547 void newUserCreatedLILPw(int userHandle) { 14548 // Adding a user requires updating runtime permissions for system apps. 14549 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 14550 } 14551 14552 @Override 14553 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 14554 mContext.enforceCallingOrSelfPermission( 14555 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 14556 "Only package verification agents can read the verifier device identity"); 14557 14558 synchronized (mPackages) { 14559 return mSettings.getVerifierDeviceIdentityLPw(); 14560 } 14561 } 14562 14563 @Override 14564 public void setPermissionEnforced(String permission, boolean enforced) { 14565 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 14566 if (READ_EXTERNAL_STORAGE.equals(permission)) { 14567 synchronized (mPackages) { 14568 if (mSettings.mReadExternalStorageEnforced == null 14569 || mSettings.mReadExternalStorageEnforced != enforced) { 14570 mSettings.mReadExternalStorageEnforced = enforced; 14571 mSettings.writeLPr(); 14572 } 14573 } 14574 // kill any non-foreground processes so we restart them and 14575 // grant/revoke the GID. 14576 final IActivityManager am = ActivityManagerNative.getDefault(); 14577 if (am != null) { 14578 final long token = Binder.clearCallingIdentity(); 14579 try { 14580 am.killProcessesBelowForeground("setPermissionEnforcement"); 14581 } catch (RemoteException e) { 14582 } finally { 14583 Binder.restoreCallingIdentity(token); 14584 } 14585 } 14586 } else { 14587 throw new IllegalArgumentException("No selective enforcement for " + permission); 14588 } 14589 } 14590 14591 @Override 14592 @Deprecated 14593 public boolean isPermissionEnforced(String permission) { 14594 return true; 14595 } 14596 14597 @Override 14598 public boolean isStorageLow() { 14599 final long token = Binder.clearCallingIdentity(); 14600 try { 14601 final DeviceStorageMonitorInternal 14602 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 14603 if (dsm != null) { 14604 return dsm.isMemoryLow(); 14605 } else { 14606 return false; 14607 } 14608 } finally { 14609 Binder.restoreCallingIdentity(token); 14610 } 14611 } 14612 14613 @Override 14614 public IPackageInstaller getPackageInstaller() { 14615 return mInstallerService; 14616 } 14617 14618 private boolean userNeedsBadging(int userId) { 14619 int index = mUserNeedsBadging.indexOfKey(userId); 14620 if (index < 0) { 14621 final UserInfo userInfo; 14622 final long token = Binder.clearCallingIdentity(); 14623 try { 14624 userInfo = sUserManager.getUserInfo(userId); 14625 } finally { 14626 Binder.restoreCallingIdentity(token); 14627 } 14628 final boolean b; 14629 if (userInfo != null && userInfo.isManagedProfile()) { 14630 b = true; 14631 } else { 14632 b = false; 14633 } 14634 mUserNeedsBadging.put(userId, b); 14635 return b; 14636 } 14637 return mUserNeedsBadging.valueAt(index); 14638 } 14639 14640 @Override 14641 public KeySet getKeySetByAlias(String packageName, String alias) { 14642 if (packageName == null || alias == null) { 14643 return null; 14644 } 14645 synchronized(mPackages) { 14646 final PackageParser.Package pkg = mPackages.get(packageName); 14647 if (pkg == null) { 14648 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14649 throw new IllegalArgumentException("Unknown package: " + packageName); 14650 } 14651 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14652 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 14653 } 14654 } 14655 14656 @Override 14657 public KeySet getSigningKeySet(String packageName) { 14658 if (packageName == null) { 14659 return null; 14660 } 14661 synchronized(mPackages) { 14662 final PackageParser.Package pkg = mPackages.get(packageName); 14663 if (pkg == null) { 14664 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14665 throw new IllegalArgumentException("Unknown package: " + packageName); 14666 } 14667 if (pkg.applicationInfo.uid != Binder.getCallingUid() 14668 && Process.SYSTEM_UID != Binder.getCallingUid()) { 14669 throw new SecurityException("May not access signing KeySet of other apps."); 14670 } 14671 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14672 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 14673 } 14674 } 14675 14676 @Override 14677 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 14678 if (packageName == null || ks == null) { 14679 return false; 14680 } 14681 synchronized(mPackages) { 14682 final PackageParser.Package pkg = mPackages.get(packageName); 14683 if (pkg == null) { 14684 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14685 throw new IllegalArgumentException("Unknown package: " + packageName); 14686 } 14687 IBinder ksh = ks.getToken(); 14688 if (ksh instanceof KeySetHandle) { 14689 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14690 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 14691 } 14692 return false; 14693 } 14694 } 14695 14696 @Override 14697 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 14698 if (packageName == null || ks == null) { 14699 return false; 14700 } 14701 synchronized(mPackages) { 14702 final PackageParser.Package pkg = mPackages.get(packageName); 14703 if (pkg == null) { 14704 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14705 throw new IllegalArgumentException("Unknown package: " + packageName); 14706 } 14707 IBinder ksh = ks.getToken(); 14708 if (ksh instanceof KeySetHandle) { 14709 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14710 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 14711 } 14712 return false; 14713 } 14714 } 14715 14716 public void getUsageStatsIfNoPackageUsageInfo() { 14717 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 14718 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 14719 if (usm == null) { 14720 throw new IllegalStateException("UsageStatsManager must be initialized"); 14721 } 14722 long now = System.currentTimeMillis(); 14723 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 14724 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 14725 String packageName = entry.getKey(); 14726 PackageParser.Package pkg = mPackages.get(packageName); 14727 if (pkg == null) { 14728 continue; 14729 } 14730 UsageStats usage = entry.getValue(); 14731 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 14732 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 14733 } 14734 } 14735 } 14736 14737 /** 14738 * Check and throw if the given before/after packages would be considered a 14739 * downgrade. 14740 */ 14741 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 14742 throws PackageManagerException { 14743 if (after.versionCode < before.mVersionCode) { 14744 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14745 "Update version code " + after.versionCode + " is older than current " 14746 + before.mVersionCode); 14747 } else if (after.versionCode == before.mVersionCode) { 14748 if (after.baseRevisionCode < before.baseRevisionCode) { 14749 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14750 "Update base revision code " + after.baseRevisionCode 14751 + " is older than current " + before.baseRevisionCode); 14752 } 14753 14754 if (!ArrayUtils.isEmpty(after.splitNames)) { 14755 for (int i = 0; i < after.splitNames.length; i++) { 14756 final String splitName = after.splitNames[i]; 14757 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 14758 if (j != -1) { 14759 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 14760 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14761 "Update split " + splitName + " revision code " 14762 + after.splitRevisionCodes[i] + " is older than current " 14763 + before.splitRevisionCodes[j]); 14764 } 14765 } 14766 } 14767 } 14768 } 14769 } 14770 14771 private static class MoveCallbacks extends Handler { 14772 private static final int MSG_CREATED = 1; 14773 private static final int MSG_STATUS_CHANGED = 2; 14774 14775 private final RemoteCallbackList<IPackageMoveObserver> 14776 mCallbacks = new RemoteCallbackList<>(); 14777 14778 private final SparseIntArray mLastStatus = new SparseIntArray(); 14779 14780 public MoveCallbacks(Looper looper) { 14781 super(looper); 14782 } 14783 14784 public void register(IPackageMoveObserver callback) { 14785 mCallbacks.register(callback); 14786 } 14787 14788 public void unregister(IPackageMoveObserver callback) { 14789 mCallbacks.unregister(callback); 14790 } 14791 14792 @Override 14793 public void handleMessage(Message msg) { 14794 final SomeArgs args = (SomeArgs) msg.obj; 14795 final int n = mCallbacks.beginBroadcast(); 14796 for (int i = 0; i < n; i++) { 14797 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 14798 try { 14799 invokeCallback(callback, msg.what, args); 14800 } catch (RemoteException ignored) { 14801 } 14802 } 14803 mCallbacks.finishBroadcast(); 14804 args.recycle(); 14805 } 14806 14807 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 14808 throws RemoteException { 14809 switch (what) { 14810 case MSG_CREATED: { 14811 callback.onCreated(args.argi1, (Bundle) args.arg2); 14812 break; 14813 } 14814 case MSG_STATUS_CHANGED: { 14815 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 14816 break; 14817 } 14818 } 14819 } 14820 14821 private void notifyCreated(int moveId, Bundle extras) { 14822 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 14823 14824 final SomeArgs args = SomeArgs.obtain(); 14825 args.argi1 = moveId; 14826 args.arg2 = extras; 14827 obtainMessage(MSG_CREATED, args).sendToTarget(); 14828 } 14829 14830 private void notifyStatusChanged(int moveId, int status) { 14831 notifyStatusChanged(moveId, status, -1); 14832 } 14833 14834 private void notifyStatusChanged(int moveId, int status, long estMillis) { 14835 Slog.v(TAG, "Move " + moveId + " status " + status); 14836 14837 final SomeArgs args = SomeArgs.obtain(); 14838 args.argi1 = moveId; 14839 args.argi2 = status; 14840 args.arg3 = estMillis; 14841 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 14842 14843 synchronized (mLastStatus) { 14844 mLastStatus.put(moveId, status); 14845 } 14846 } 14847 } 14848} 14849