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 17 package com.android.server.pm; 18 19 import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 20 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 21 import static android.Manifest.permission.WRITE_MEDIA_STORAGE; 22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 27 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 28 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 29 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 30 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 31 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 32 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 33 import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 34 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 35 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 36 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 37 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 38 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 39 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 40 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 41 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 42 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 43 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 44 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 45 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 46 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 47 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 48 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 49 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 50 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 51 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 52 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 53 import static android.content.pm.PackageManager.INSTALL_INTERNAL; 54 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 55 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 56 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 57 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 58 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 59 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 60 import static android.content.pm.PackageManager.MATCH_ALL; 61 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 62 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 63 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 64 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 65 import static android.content.pm.PackageManager.PERMISSION_DENIED; 66 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 67 import static android.content.pm.PackageParser.isApkFile; 68 import static android.os.Process.PACKAGE_INFO_GID; 69 import static android.os.Process.SYSTEM_UID; 70 import static android.system.OsConstants.O_CREAT; 71 import static android.system.OsConstants.O_RDWR; 72 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 73 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER; 74 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 75 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 76 import static com.android.internal.util.ArrayUtils.appendInt; 77 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 78 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 79 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 80 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 81 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 82 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 83 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 84 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 85 86 import android.Manifest; 87 import android.app.ActivityManager; 88 import android.app.ActivityManagerNative; 89 import android.app.AppGlobals; 90 import android.app.IActivityManager; 91 import android.app.admin.IDevicePolicyManager; 92 import android.app.backup.IBackupManager; 93 import android.app.usage.UsageStats; 94 import android.app.usage.UsageStatsManager; 95 import android.content.BroadcastReceiver; 96 import android.content.ComponentName; 97 import android.content.Context; 98 import android.content.IIntentReceiver; 99 import android.content.Intent; 100 import android.content.IntentFilter; 101 import android.content.IntentSender; 102 import android.content.IntentSender.SendIntentException; 103 import android.content.ServiceConnection; 104 import android.content.pm.ActivityInfo; 105 import android.content.pm.ApplicationInfo; 106 import android.content.pm.FeatureInfo; 107 import android.content.pm.IOnPermissionsChangeListener; 108 import android.content.pm.IPackageDataObserver; 109 import android.content.pm.IPackageDeleteObserver; 110 import android.content.pm.IPackageDeleteObserver2; 111 import android.content.pm.IPackageInstallObserver2; 112 import android.content.pm.IPackageInstaller; 113 import android.content.pm.IPackageManager; 114 import android.content.pm.IPackageMoveObserver; 115 import android.content.pm.IPackageStatsObserver; 116 import android.content.pm.InstrumentationInfo; 117 import android.content.pm.IntentFilterVerificationInfo; 118 import android.content.pm.KeySet; 119 import android.content.pm.ManifestDigest; 120 import android.content.pm.PackageCleanItem; 121 import android.content.pm.PackageInfo; 122 import android.content.pm.PackageInfoLite; 123 import android.content.pm.PackageInstaller; 124 import android.content.pm.PackageManager; 125 import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 126 import android.content.pm.PackageManagerInternal; 127 import android.content.pm.PackageParser; 128 import android.content.pm.PackageParser.ActivityIntentInfo; 129 import android.content.pm.PackageParser.PackageLite; 130 import android.content.pm.PackageParser.PackageParserException; 131 import android.content.pm.PackageStats; 132 import android.content.pm.PackageUserState; 133 import android.content.pm.ParceledListSlice; 134 import android.content.pm.PermissionGroupInfo; 135 import android.content.pm.PermissionInfo; 136 import android.content.pm.ProviderInfo; 137 import android.content.pm.ResolveInfo; 138 import android.content.pm.ServiceInfo; 139 import android.content.pm.Signature; 140 import android.content.pm.UserInfo; 141 import android.content.pm.VerificationParams; 142 import android.content.pm.VerifierDeviceIdentity; 143 import android.content.pm.VerifierInfo; 144 import android.content.res.Resources; 145 import android.hardware.display.DisplayManager; 146 import android.net.Uri; 147 import android.os.Debug; 148 import android.os.Binder; 149 import android.os.Build; 150 import android.os.Bundle; 151 import android.os.Environment; 152 import android.os.Environment.UserEnvironment; 153 import android.os.FileUtils; 154 import android.os.Handler; 155 import android.os.IBinder; 156 import android.os.Looper; 157 import android.os.Message; 158 import android.os.Parcel; 159 import android.os.ParcelFileDescriptor; 160 import android.os.Process; 161 import android.os.RemoteCallbackList; 162 import android.os.RemoteException; 163 import android.os.SELinux; 164 import android.os.ServiceManager; 165 import android.os.SystemClock; 166 import android.os.SystemProperties; 167 import android.os.UserHandle; 168 import android.os.UserManager; 169 import android.os.storage.IMountService; 170 import android.os.storage.MountServiceInternal; 171 import android.os.storage.StorageEventListener; 172 import android.os.storage.StorageManager; 173 import android.os.storage.VolumeInfo; 174 import android.os.storage.VolumeRecord; 175 import android.security.KeyStore; 176 import android.security.SystemKeyStore; 177 import android.system.ErrnoException; 178 import android.system.Os; 179 import android.system.StructStat; 180 import android.text.TextUtils; 181 import android.text.format.DateUtils; 182 import android.util.ArrayMap; 183 import android.util.ArraySet; 184 import android.util.AtomicFile; 185 import android.util.DisplayMetrics; 186 import android.util.EventLog; 187 import android.util.ExceptionUtils; 188 import android.util.Log; 189 import android.util.LogPrinter; 190 import android.util.MathUtils; 191 import android.util.PrintStreamPrinter; 192 import android.util.Slog; 193 import android.util.SparseArray; 194 import android.util.SparseBooleanArray; 195 import android.util.SparseIntArray; 196 import android.util.Xml; 197 import android.view.Display; 198 199 import dalvik.system.DexFile; 200 import dalvik.system.VMRuntime; 201 202 import libcore.io.IoUtils; 203 import libcore.util.EmptyArray; 204 205 import com.android.internal.R; 206 import com.android.internal.annotations.GuardedBy; 207 import com.android.internal.app.IMediaContainerService; 208 import com.android.internal.app.ResolverActivity; 209 import com.android.internal.content.NativeLibraryHelper; 210 import com.android.internal.content.PackageHelper; 211 import com.android.internal.os.IParcelFileDescriptorFactory; 212 import com.android.internal.os.SomeArgs; 213 import com.android.internal.os.Zygote; 214 import com.android.internal.util.ArrayUtils; 215 import com.android.internal.util.FastPrintWriter; 216 import com.android.internal.util.FastXmlSerializer; 217 import com.android.internal.util.IndentingPrintWriter; 218 import com.android.internal.util.Preconditions; 219 import com.android.server.EventLogTags; 220 import com.android.server.FgThread; 221 import com.android.server.IntentResolver; 222 import com.android.server.LocalServices; 223 import com.android.server.ServiceThread; 224 import com.android.server.SystemConfig; 225 import com.android.server.Watchdog; 226 import com.android.server.pm.PermissionsState.PermissionState; 227 import com.android.server.pm.Settings.DatabaseVersion; 228 import com.android.server.pm.Settings.VersionInfo; 229 import com.android.server.storage.DeviceStorageMonitorInternal; 230 231 import org.xmlpull.v1.XmlPullParser; 232 import org.xmlpull.v1.XmlPullParserException; 233 import org.xmlpull.v1.XmlSerializer; 234 235 import java.io.BufferedInputStream; 236 import java.io.BufferedOutputStream; 237 import java.io.BufferedReader; 238 import java.io.ByteArrayInputStream; 239 import java.io.ByteArrayOutputStream; 240 import java.io.File; 241 import java.io.FileDescriptor; 242 import java.io.FileNotFoundException; 243 import java.io.FileOutputStream; 244 import java.io.FileReader; 245 import java.io.FilenameFilter; 246 import java.io.IOException; 247 import java.io.InputStream; 248 import java.io.PrintWriter; 249 import java.nio.charset.StandardCharsets; 250 import java.security.NoSuchAlgorithmException; 251 import java.security.PublicKey; 252 import java.security.cert.CertificateEncodingException; 253 import java.security.cert.CertificateException; 254 import java.text.SimpleDateFormat; 255 import java.util.ArrayList; 256 import java.util.Arrays; 257 import java.util.Collection; 258 import java.util.Collections; 259 import java.util.Comparator; 260 import java.util.Date; 261 import java.util.Iterator; 262 import java.util.List; 263 import java.util.Map; 264 import java.util.Objects; 265 import java.util.Set; 266 import java.util.concurrent.CountDownLatch; 267 import java.util.concurrent.TimeUnit; 268 import java.util.concurrent.atomic.AtomicBoolean; 269 import java.util.concurrent.atomic.AtomicInteger; 270 import java.util.concurrent.atomic.AtomicLong; 271 272 /** 273 * Keep track of all those .apks everywhere. 274 * 275 * This is very central to the platform's security; please run the unit 276 * tests whenever making modifications here: 277 * 278 mmm frameworks/base/tests/AndroidTests 279 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 280 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 281 * 282 * {@hide} 283 */ 284 public class PackageManagerService extends IPackageManager.Stub { 285 static final String TAG = "PackageManager"; 286 static final boolean DEBUG_SETTINGS = false; 287 static final boolean DEBUG_PREFERRED = false; 288 static final boolean DEBUG_UPGRADE = false; 289 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 290 private static final boolean DEBUG_BACKUP = false; 291 private static final boolean DEBUG_INSTALL = false; 292 private static final boolean DEBUG_REMOVE = false; 293 private static final boolean DEBUG_BROADCASTS = false; 294 private static final boolean DEBUG_SHOW_INFO = false; 295 private static final boolean DEBUG_PACKAGE_INFO = false; 296 private static final boolean DEBUG_INTENT_MATCHING = false; 297 private static final boolean DEBUG_PACKAGE_SCANNING = false; 298 private static final boolean DEBUG_VERIFY = false; 299 private static final boolean DEBUG_DEXOPT = false; 300 private static final boolean DEBUG_FILTERS = false; 301 private static final boolean DEBUG_ABI_SELECTION = false; 302 303 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 304 305 private static final int RADIO_UID = Process.PHONE_UID; 306 private static final int LOG_UID = Process.LOG_UID; 307 private static final int NFC_UID = Process.NFC_UID; 308 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 309 private static final int SHELL_UID = Process.SHELL_UID; 310 311 // Cap the size of permission trees that 3rd party apps can define 312 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 313 314 // Suffix used during package installation when copying/moving 315 // package apks to install directory. 316 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 317 318 static final int SCAN_NO_DEX = 1<<1; 319 static final int SCAN_FORCE_DEX = 1<<2; 320 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 321 static final int SCAN_NEW_INSTALL = 1<<4; 322 static final int SCAN_NO_PATHS = 1<<5; 323 static final int SCAN_UPDATE_TIME = 1<<6; 324 static final int SCAN_DEFER_DEX = 1<<7; 325 static final int SCAN_BOOTING = 1<<8; 326 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 327 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 328 static final int SCAN_REPLACING = 1<<11; 329 static final int SCAN_REQUIRE_KNOWN = 1<<12; 330 static final int SCAN_MOVE = 1<<13; 331 static final int SCAN_INITIAL = 1<<14; 332 333 static final int REMOVE_CHATTY = 1<<16; 334 335 private static final int[] EMPTY_INT_ARRAY = new int[0]; 336 337 /** 338 * Timeout (in milliseconds) after which the watchdog should declare that 339 * our handler thread is wedged. The usual default for such things is one 340 * minute but we sometimes do very lengthy I/O operations on this thread, 341 * such as installing multi-gigabyte applications, so ours needs to be longer. 342 */ 343 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 344 345 /** 346 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 347 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 348 * settings entry if available, otherwise we use the hardcoded default. If it's been 349 * more than this long since the last fstrim, we force one during the boot sequence. 350 * 351 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 352 * one gets run at the next available charging+idle time. This final mandatory 353 * no-fstrim check kicks in only of the other scheduling criteria is never met. 354 */ 355 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 356 357 /** 358 * Whether verification is enabled by default. 359 */ 360 private static final boolean DEFAULT_VERIFY_ENABLE = true; 361 362 /** 363 * The default maximum time to wait for the verification agent to return in 364 * milliseconds. 365 */ 366 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 367 368 /** 369 * The default response for package verification timeout. 370 * 371 * This can be either PackageManager.VERIFICATION_ALLOW or 372 * PackageManager.VERIFICATION_REJECT. 373 */ 374 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 375 376 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 377 378 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 379 DEFAULT_CONTAINER_PACKAGE, 380 "com.android.defcontainer.DefaultContainerService"); 381 382 private static final String KILL_APP_REASON_GIDS_CHANGED = 383 "permission grant or revoke changed gids"; 384 385 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 386 "permissions revoked"; 387 388 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 389 390 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 391 392 /** Permission grant: not grant the permission. */ 393 private static final int GRANT_DENIED = 1; 394 395 /** Permission grant: grant the permission as an install permission. */ 396 private static final int GRANT_INSTALL = 2; 397 398 /** Permission grant: grant the permission as an install permission for a legacy app. */ 399 private static final int GRANT_INSTALL_LEGACY = 3; 400 401 /** Permission grant: grant the permission as a runtime one. */ 402 private static final int GRANT_RUNTIME = 4; 403 404 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 405 private static final int GRANT_UPGRADE = 5; 406 407 /** Canonical intent used to identify what counts as a "web browser" app */ 408 private static final Intent sBrowserIntent; 409 static { 410 sBrowserIntent = new Intent(); 411 sBrowserIntent.setAction(Intent.ACTION_VIEW); 412 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 413 sBrowserIntent.setData(Uri.parse("http:")); 414 } 415 416 final ServiceThread mHandlerThread; 417 418 final PackageHandler mHandler; 419 420 /** 421 * Messages for {@link #mHandler} that need to wait for system ready before 422 * being dispatched. 423 */ 424 private ArrayList<Message> mPostSystemReadyMessages; 425 426 final int mSdkVersion = Build.VERSION.SDK_INT; 427 428 final Context mContext; 429 final boolean mFactoryTest; 430 final boolean mOnlyCore; 431 final boolean mLazyDexOpt; 432 final long mDexOptLRUThresholdInMills; 433 final DisplayMetrics mMetrics; 434 final int mDefParseFlags; 435 final String[] mSeparateProcesses; 436 final boolean mIsUpgrade; 437 438 // This is where all application persistent data goes. 439 final File mAppDataDir; 440 441 // This is where all application persistent data goes for secondary users. 442 final File mUserAppDataDir; 443 444 /** The location for ASEC container files on internal storage. */ 445 final String mAsecInternalPath; 446 447 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 448 // LOCK HELD. Can be called with mInstallLock held. 449 @GuardedBy("mInstallLock") 450 final Installer mInstaller; 451 452 /** Directory where installed third-party apps stored */ 453 final File mAppInstallDir; 454 455 /** 456 * Directory to which applications installed internally have their 457 * 32 bit native libraries copied. 458 */ 459 private File mAppLib32InstallDir; 460 461 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 462 // apps. 463 final File mDrmAppPrivateInstallDir; 464 465 // ---------------------------------------------------------------- 466 467 // Lock for state used when installing and doing other long running 468 // operations. Methods that must be called with this lock held have 469 // the suffix "LI". 470 final Object mInstallLock = new Object(); 471 472 // ---------------------------------------------------------------- 473 474 // Keys are String (package name), values are Package. This also serves 475 // as the lock for the global state. Methods that must be called with 476 // this lock held have the prefix "LP". 477 @GuardedBy("mPackages") 478 final ArrayMap<String, PackageParser.Package> mPackages = 479 new ArrayMap<String, PackageParser.Package>(); 480 481 // Tracks available target package names -> overlay package paths. 482 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 483 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 484 485 /** 486 * Tracks new system packages [received in an OTA] that we expect to 487 * find updated user-installed versions. Keys are package name, values 488 * are package location. 489 */ 490 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 491 492 /** 493 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 494 */ 495 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 496 /** 497 * Whether or not system app permissions should be promoted from install to runtime. 498 */ 499 boolean mPromoteSystemApps; 500 501 final Settings mSettings; 502 boolean mRestoredSettings; 503 504 // System configuration read by SystemConfig. 505 final int[] mGlobalGids; 506 final SparseArray<ArraySet<String>> mSystemPermissions; 507 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 508 509 // If mac_permissions.xml was found for seinfo labeling. 510 boolean mFoundPolicyFile; 511 512 // If a recursive restorecon of /data/data/<pkg> is needed. 513 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 514 515 public static final class SharedLibraryEntry { 516 public final String path; 517 public final String apk; 518 SharedLibraryEntry(String _path, String _apk)519 SharedLibraryEntry(String _path, String _apk) { 520 path = _path; 521 apk = _apk; 522 } 523 } 524 525 // Currently known shared libraries. 526 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 527 new ArrayMap<String, SharedLibraryEntry>(); 528 529 // All available activities, for your resolving pleasure. 530 final ActivityIntentResolver mActivities = 531 new ActivityIntentResolver(); 532 533 // All available receivers, for your resolving pleasure. 534 final ActivityIntentResolver mReceivers = 535 new ActivityIntentResolver(); 536 537 // All available services, for your resolving pleasure. 538 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 539 540 // All available providers, for your resolving pleasure. 541 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 542 543 // Mapping from provider base names (first directory in content URI codePath) 544 // to the provider information. 545 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 546 new ArrayMap<String, PackageParser.Provider>(); 547 548 // Mapping from instrumentation class names to info about them. 549 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 550 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 551 552 // Mapping from permission names to info about them. 553 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 554 new ArrayMap<String, PackageParser.PermissionGroup>(); 555 556 // Packages whose data we have transfered into another package, thus 557 // should no longer exist. 558 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 559 560 // Broadcast actions that are only available to the system. 561 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 562 563 /** List of packages waiting for verification. */ 564 final SparseArray<PackageVerificationState> mPendingVerification 565 = new SparseArray<PackageVerificationState>(); 566 567 /** Set of packages associated with each app op permission. */ 568 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 569 570 final PackageInstallerService mInstallerService; 571 572 private final PackageDexOptimizer mPackageDexOptimizer; 573 574 private AtomicInteger mNextMoveId = new AtomicInteger(); 575 private final MoveCallbacks mMoveCallbacks; 576 577 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 578 579 // Cache of users who need badging. 580 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 581 582 /** Token for keys in mPendingVerification. */ 583 private int mPendingVerificationToken = 0; 584 585 volatile boolean mSystemReady; 586 volatile boolean mSafeMode; 587 volatile boolean mHasSystemUidErrors; 588 589 ApplicationInfo mAndroidApplication; 590 final ActivityInfo mResolveActivity = new ActivityInfo(); 591 final ResolveInfo mResolveInfo = new ResolveInfo(); 592 ComponentName mResolveComponentName; 593 PackageParser.Package mPlatformPackage; 594 ComponentName mCustomResolverComponentName; 595 596 boolean mResolverReplaced = false; 597 598 private final ComponentName mIntentFilterVerifierComponent; 599 private int mIntentFilterVerificationToken = 0; 600 601 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 602 = new SparseArray<IntentFilterVerificationState>(); 603 604 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 605 new DefaultPermissionGrantPolicy(this); 606 607 private static class IFVerificationParams { 608 PackageParser.Package pkg; 609 boolean replacing; 610 int userId; 611 int verifierUid; 612 IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, int _userId, int _verifierUid)613 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 614 int _userId, int _verifierUid) { 615 pkg = _pkg; 616 replacing = _replacing; 617 userId = _userId; 618 replacing = _replacing; 619 verifierUid = _verifierUid; 620 } 621 } 622 623 private interface IntentFilterVerifier<T extends IntentFilter> { addOneIntentFilterVerification(int verifierId, int userId, int verificationId, T filter, String packageName)624 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 625 T filter, String packageName); startVerifications(int userId)626 void startVerifications(int userId); receiveVerificationResponse(int verificationId)627 void receiveVerificationResponse(int verificationId); 628 } 629 630 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 631 private Context mContext; 632 private ComponentName mIntentFilterVerifierComponent; 633 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 634 IntentVerifierProxy(Context context, ComponentName verifierComponent)635 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 636 mContext = context; 637 mIntentFilterVerifierComponent = verifierComponent; 638 } 639 getDefaultScheme()640 private String getDefaultScheme() { 641 return IntentFilter.SCHEME_HTTPS; 642 } 643 644 @Override startVerifications(int userId)645 public void startVerifications(int userId) { 646 // Launch verifications requests 647 int count = mCurrentIntentFilterVerifications.size(); 648 for (int n=0; n<count; n++) { 649 int verificationId = mCurrentIntentFilterVerifications.get(n); 650 final IntentFilterVerificationState ivs = 651 mIntentFilterVerificationStates.get(verificationId); 652 653 String packageName = ivs.getPackageName(); 654 655 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 656 final int filterCount = filters.size(); 657 ArraySet<String> domainsSet = new ArraySet<>(); 658 for (int m=0; m<filterCount; m++) { 659 PackageParser.ActivityIntentInfo filter = filters.get(m); 660 domainsSet.addAll(filter.getHostsList()); 661 } 662 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 663 synchronized (mPackages) { 664 if (mSettings.createIntentFilterVerificationIfNeededLPw( 665 packageName, domainsList) != null) { 666 scheduleWriteSettingsLocked(); 667 } 668 } 669 sendVerificationRequest(userId, verificationId, ivs); 670 } 671 mCurrentIntentFilterVerifications.clear(); 672 } 673 sendVerificationRequest(int userId, int verificationId, IntentFilterVerificationState ivs)674 private void sendVerificationRequest(int userId, int verificationId, 675 IntentFilterVerificationState ivs) { 676 677 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 678 verificationIntent.putExtra( 679 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 680 verificationId); 681 verificationIntent.putExtra( 682 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 683 getDefaultScheme()); 684 verificationIntent.putExtra( 685 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 686 ivs.getHostsString()); 687 verificationIntent.putExtra( 688 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 689 ivs.getPackageName()); 690 verificationIntent.setComponent(mIntentFilterVerifierComponent); 691 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 692 693 UserHandle user = new UserHandle(userId); 694 mContext.sendBroadcastAsUser(verificationIntent, user); 695 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 696 "Sending IntentFilter verification broadcast"); 697 } 698 receiveVerificationResponse(int verificationId)699 public void receiveVerificationResponse(int verificationId) { 700 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 701 702 final boolean verified = ivs.isVerified(); 703 704 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 705 final int count = filters.size(); 706 if (DEBUG_DOMAIN_VERIFICATION) { 707 Slog.i(TAG, "Received verification response " + verificationId 708 + " for " + count + " filters, verified=" + verified); 709 } 710 for (int n=0; n<count; n++) { 711 PackageParser.ActivityIntentInfo filter = filters.get(n); 712 filter.setVerified(verified); 713 714 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 715 + " verified with result:" + verified + " and hosts:" 716 + ivs.getHostsString()); 717 } 718 719 mIntentFilterVerificationStates.remove(verificationId); 720 721 final String packageName = ivs.getPackageName(); 722 IntentFilterVerificationInfo ivi = null; 723 724 synchronized (mPackages) { 725 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 726 } 727 if (ivi == null) { 728 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 729 + verificationId + " packageName:" + packageName); 730 return; 731 } 732 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 733 "Updating IntentFilterVerificationInfo for package " + packageName 734 +" verificationId:" + verificationId); 735 736 synchronized (mPackages) { 737 if (verified) { 738 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 739 } else { 740 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 741 } 742 scheduleWriteSettingsLocked(); 743 744 final int userId = ivs.getUserId(); 745 if (userId != UserHandle.USER_ALL) { 746 final int userStatus = 747 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 748 749 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 750 boolean needUpdate = false; 751 752 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 753 // already been set by the User thru the Disambiguation dialog 754 switch (userStatus) { 755 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 756 if (verified) { 757 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 758 } else { 759 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 760 } 761 needUpdate = true; 762 break; 763 764 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 765 if (verified) { 766 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 767 needUpdate = true; 768 } 769 break; 770 771 default: 772 // Nothing to do 773 } 774 775 if (needUpdate) { 776 mSettings.updateIntentFilterVerificationStatusLPw( 777 packageName, updatedStatus, userId); 778 scheduleWritePackageRestrictionsLocked(userId); 779 } 780 } 781 } 782 } 783 784 @Override addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, ActivityIntentInfo filter, String packageName)785 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 786 ActivityIntentInfo filter, String packageName) { 787 if (!hasValidDomains(filter)) { 788 return false; 789 } 790 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 791 if (ivs == null) { 792 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 793 packageName); 794 } 795 if (DEBUG_DOMAIN_VERIFICATION) { 796 Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter); 797 } 798 ivs.addFilter(filter); 799 return true; 800 } 801 createDomainVerificationState(int verifierUid, int userId, int verificationId, String packageName)802 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 803 int userId, int verificationId, String packageName) { 804 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 805 verifierUid, userId, packageName); 806 ivs.setPendingState(); 807 synchronized (mPackages) { 808 mIntentFilterVerificationStates.append(verificationId, ivs); 809 mCurrentIntentFilterVerifications.add(verificationId); 810 } 811 return ivs; 812 } 813 } 814 hasValidDomains(ActivityIntentInfo filter)815 private static boolean hasValidDomains(ActivityIntentInfo filter) { 816 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 817 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 818 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 819 } 820 821 private IntentFilterVerifier mIntentFilterVerifier; 822 823 // Set of pending broadcasts for aggregating enable/disable of components. 824 static class PendingPackageBroadcasts { 825 // for each user id, a map of <package name -> components within that package> 826 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 827 PendingPackageBroadcasts()828 public PendingPackageBroadcasts() { 829 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 830 } 831 get(int userId, String packageName)832 public ArrayList<String> get(int userId, String packageName) { 833 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 834 return packages.get(packageName); 835 } 836 put(int userId, String packageName, ArrayList<String> components)837 public void put(int userId, String packageName, ArrayList<String> components) { 838 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 839 packages.put(packageName, components); 840 } 841 remove(int userId, String packageName)842 public void remove(int userId, String packageName) { 843 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 844 if (packages != null) { 845 packages.remove(packageName); 846 } 847 } 848 remove(int userId)849 public void remove(int userId) { 850 mUidMap.remove(userId); 851 } 852 userIdCount()853 public int userIdCount() { 854 return mUidMap.size(); 855 } 856 userIdAt(int n)857 public int userIdAt(int n) { 858 return mUidMap.keyAt(n); 859 } 860 packagesForUserId(int userId)861 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 862 return mUidMap.get(userId); 863 } 864 size()865 public int size() { 866 // total number of pending broadcast entries across all userIds 867 int num = 0; 868 for (int i = 0; i< mUidMap.size(); i++) { 869 num += mUidMap.valueAt(i).size(); 870 } 871 return num; 872 } 873 clear()874 public void clear() { 875 mUidMap.clear(); 876 } 877 getOrAllocate(int userId)878 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 879 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 880 if (map == null) { 881 map = new ArrayMap<String, ArrayList<String>>(); 882 mUidMap.put(userId, map); 883 } 884 return map; 885 } 886 } 887 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 888 889 // Service Connection to remote media container service to copy 890 // package uri's from external media onto secure containers 891 // or internal storage. 892 private IMediaContainerService mContainerService = null; 893 894 static final int SEND_PENDING_BROADCAST = 1; 895 static final int MCS_BOUND = 3; 896 static final int END_COPY = 4; 897 static final int INIT_COPY = 5; 898 static final int MCS_UNBIND = 6; 899 static final int START_CLEANING_PACKAGE = 7; 900 static final int FIND_INSTALL_LOC = 8; 901 static final int POST_INSTALL = 9; 902 static final int MCS_RECONNECT = 10; 903 static final int MCS_GIVE_UP = 11; 904 static final int UPDATED_MEDIA_STATUS = 12; 905 static final int WRITE_SETTINGS = 13; 906 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 907 static final int PACKAGE_VERIFIED = 15; 908 static final int CHECK_PENDING_VERIFICATION = 16; 909 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 910 static final int INTENT_FILTER_VERIFIED = 18; 911 912 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 913 914 // Delay time in millisecs 915 static final int BROADCAST_DELAY = 10 * 1000; 916 917 static UserManagerService sUserManager; 918 919 // Stores a list of users whose package restrictions file needs to be updated 920 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 921 922 final private DefaultContainerConnection mDefContainerConn = 923 new DefaultContainerConnection(); 924 class DefaultContainerConnection implements ServiceConnection { onServiceConnected(ComponentName name, IBinder service)925 public void onServiceConnected(ComponentName name, IBinder service) { 926 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 927 IMediaContainerService imcs = 928 IMediaContainerService.Stub.asInterface(service); 929 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 930 } 931 onServiceDisconnected(ComponentName name)932 public void onServiceDisconnected(ComponentName name) { 933 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 934 } 935 } 936 937 // Recordkeeping of restore-after-install operations that are currently in flight 938 // between the Package Manager and the Backup Manager 939 class PostInstallData { 940 public InstallArgs args; 941 public PackageInstalledInfo res; 942 PostInstallData(InstallArgs _a, PackageInstalledInfo _r)943 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 944 args = _a; 945 res = _r; 946 } 947 } 948 949 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 950 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 951 952 // XML tags for backup/restore of various bits of state 953 private static final String TAG_PREFERRED_BACKUP = "pa"; 954 private static final String TAG_DEFAULT_APPS = "da"; 955 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 956 957 final String mRequiredVerifierPackage; 958 final String mRequiredInstallerPackage; 959 960 private final PackageUsage mPackageUsage = new PackageUsage(); 961 962 private class PackageUsage { 963 private static final int WRITE_INTERVAL 964 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 965 966 private final Object mFileLock = new Object(); 967 private final AtomicLong mLastWritten = new AtomicLong(0); 968 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 969 970 private boolean mIsHistoricalPackageUsageAvailable = true; 971 isHistoricalPackageUsageAvailable()972 boolean isHistoricalPackageUsageAvailable() { 973 return mIsHistoricalPackageUsageAvailable; 974 } 975 write(boolean force)976 void write(boolean force) { 977 if (force) { 978 writeInternal(); 979 return; 980 } 981 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 982 && !DEBUG_DEXOPT) { 983 return; 984 } 985 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 986 new Thread("PackageUsage_DiskWriter") { 987 @Override 988 public void run() { 989 try { 990 writeInternal(); 991 } finally { 992 mBackgroundWriteRunning.set(false); 993 } 994 } 995 }.start(); 996 } 997 } 998 writeInternal()999 private void writeInternal() { 1000 synchronized (mPackages) { 1001 synchronized (mFileLock) { 1002 AtomicFile file = getFile(); 1003 FileOutputStream f = null; 1004 try { 1005 f = file.startWrite(); 1006 BufferedOutputStream out = new BufferedOutputStream(f); 1007 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 1008 StringBuilder sb = new StringBuilder(); 1009 for (PackageParser.Package pkg : mPackages.values()) { 1010 if (pkg.mLastPackageUsageTimeInMills == 0) { 1011 continue; 1012 } 1013 sb.setLength(0); 1014 sb.append(pkg.packageName); 1015 sb.append(' '); 1016 sb.append((long)pkg.mLastPackageUsageTimeInMills); 1017 sb.append('\n'); 1018 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 1019 } 1020 out.flush(); 1021 file.finishWrite(f); 1022 } catch (IOException e) { 1023 if (f != null) { 1024 file.failWrite(f); 1025 } 1026 Log.e(TAG, "Failed to write package usage times", e); 1027 } 1028 } 1029 } 1030 mLastWritten.set(SystemClock.elapsedRealtime()); 1031 } 1032 readLP()1033 void readLP() { 1034 synchronized (mFileLock) { 1035 AtomicFile file = getFile(); 1036 BufferedInputStream in = null; 1037 try { 1038 in = new BufferedInputStream(file.openRead()); 1039 StringBuffer sb = new StringBuffer(); 1040 while (true) { 1041 String packageName = readToken(in, sb, ' '); 1042 if (packageName == null) { 1043 break; 1044 } 1045 String timeInMillisString = readToken(in, sb, '\n'); 1046 if (timeInMillisString == null) { 1047 throw new IOException("Failed to find last usage time for package " 1048 + packageName); 1049 } 1050 PackageParser.Package pkg = mPackages.get(packageName); 1051 if (pkg == null) { 1052 continue; 1053 } 1054 long timeInMillis; 1055 try { 1056 timeInMillis = Long.parseLong(timeInMillisString.toString()); 1057 } catch (NumberFormatException e) { 1058 throw new IOException("Failed to parse " + timeInMillisString 1059 + " as a long.", e); 1060 } 1061 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1062 } 1063 } catch (FileNotFoundException expected) { 1064 mIsHistoricalPackageUsageAvailable = false; 1065 } catch (IOException e) { 1066 Log.w(TAG, "Failed to read package usage times", e); 1067 } finally { 1068 IoUtils.closeQuietly(in); 1069 } 1070 } 1071 mLastWritten.set(SystemClock.elapsedRealtime()); 1072 } 1073 readToken(InputStream in, StringBuffer sb, char endOfToken)1074 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1075 throws IOException { 1076 sb.setLength(0); 1077 while (true) { 1078 int ch = in.read(); 1079 if (ch == -1) { 1080 if (sb.length() == 0) { 1081 return null; 1082 } 1083 throw new IOException("Unexpected EOF"); 1084 } 1085 if (ch == endOfToken) { 1086 return sb.toString(); 1087 } 1088 sb.append((char)ch); 1089 } 1090 } 1091 getFile()1092 private AtomicFile getFile() { 1093 File dataDir = Environment.getDataDirectory(); 1094 File systemDir = new File(dataDir, "system"); 1095 File fname = new File(systemDir, "package-usage.list"); 1096 return new AtomicFile(fname); 1097 } 1098 } 1099 1100 class PackageHandler extends Handler { 1101 private boolean mBound = false; 1102 final ArrayList<HandlerParams> mPendingInstalls = 1103 new ArrayList<HandlerParams>(); 1104 connectToService()1105 private boolean connectToService() { 1106 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1107 " DefaultContainerService"); 1108 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1109 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1110 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1111 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 1112 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1113 mBound = true; 1114 return true; 1115 } 1116 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1117 return false; 1118 } 1119 disconnectService()1120 private void disconnectService() { 1121 mContainerService = null; 1122 mBound = false; 1123 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1124 mContext.unbindService(mDefContainerConn); 1125 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1126 } 1127 PackageHandler(Looper looper)1128 PackageHandler(Looper looper) { 1129 super(looper); 1130 } 1131 handleMessage(Message msg)1132 public void handleMessage(Message msg) { 1133 try { 1134 doHandleMessage(msg); 1135 } finally { 1136 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1137 } 1138 } 1139 doHandleMessage(Message msg)1140 void doHandleMessage(Message msg) { 1141 switch (msg.what) { 1142 case INIT_COPY: { 1143 HandlerParams params = (HandlerParams) msg.obj; 1144 int idx = mPendingInstalls.size(); 1145 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1146 // If a bind was already initiated we dont really 1147 // need to do anything. The pending install 1148 // will be processed later on. 1149 if (!mBound) { 1150 // If this is the only one pending we might 1151 // have to bind to the service again. 1152 if (!connectToService()) { 1153 Slog.e(TAG, "Failed to bind to media container service"); 1154 params.serviceError(); 1155 return; 1156 } else { 1157 // Once we bind to the service, the first 1158 // pending request will be processed. 1159 mPendingInstalls.add(idx, params); 1160 } 1161 } else { 1162 mPendingInstalls.add(idx, params); 1163 // Already bound to the service. Just make 1164 // sure we trigger off processing the first request. 1165 if (idx == 0) { 1166 mHandler.sendEmptyMessage(MCS_BOUND); 1167 } 1168 } 1169 break; 1170 } 1171 case MCS_BOUND: { 1172 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1173 if (msg.obj != null) { 1174 mContainerService = (IMediaContainerService) msg.obj; 1175 } 1176 if (mContainerService == null) { 1177 if (!mBound) { 1178 // Something seriously wrong since we are not bound and we are not 1179 // waiting for connection. Bail out. 1180 Slog.e(TAG, "Cannot bind to media container service"); 1181 for (HandlerParams params : mPendingInstalls) { 1182 // Indicate service bind error 1183 params.serviceError(); 1184 } 1185 mPendingInstalls.clear(); 1186 } else { 1187 Slog.w(TAG, "Waiting to connect to media container service"); 1188 } 1189 } else if (mPendingInstalls.size() > 0) { 1190 HandlerParams params = mPendingInstalls.get(0); 1191 if (params != null) { 1192 if (params.startCopy()) { 1193 // We are done... look for more work or to 1194 // go idle. 1195 if (DEBUG_SD_INSTALL) Log.i(TAG, 1196 "Checking for more work or unbind..."); 1197 // Delete pending install 1198 if (mPendingInstalls.size() > 0) { 1199 mPendingInstalls.remove(0); 1200 } 1201 if (mPendingInstalls.size() == 0) { 1202 if (mBound) { 1203 if (DEBUG_SD_INSTALL) Log.i(TAG, 1204 "Posting delayed MCS_UNBIND"); 1205 removeMessages(MCS_UNBIND); 1206 Message ubmsg = obtainMessage(MCS_UNBIND); 1207 // Unbind after a little delay, to avoid 1208 // continual thrashing. 1209 sendMessageDelayed(ubmsg, 10000); 1210 } 1211 } else { 1212 // There are more pending requests in queue. 1213 // Just post MCS_BOUND message to trigger processing 1214 // of next pending install. 1215 if (DEBUG_SD_INSTALL) Log.i(TAG, 1216 "Posting MCS_BOUND for next work"); 1217 mHandler.sendEmptyMessage(MCS_BOUND); 1218 } 1219 } 1220 } 1221 } else { 1222 // Should never happen ideally. 1223 Slog.w(TAG, "Empty queue"); 1224 } 1225 break; 1226 } 1227 case MCS_RECONNECT: { 1228 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1229 if (mPendingInstalls.size() > 0) { 1230 if (mBound) { 1231 disconnectService(); 1232 } 1233 if (!connectToService()) { 1234 Slog.e(TAG, "Failed to bind to media container service"); 1235 for (HandlerParams params : mPendingInstalls) { 1236 // Indicate service bind error 1237 params.serviceError(); 1238 } 1239 mPendingInstalls.clear(); 1240 } 1241 } 1242 break; 1243 } 1244 case MCS_UNBIND: { 1245 // If there is no actual work left, then time to unbind. 1246 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1247 1248 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1249 if (mBound) { 1250 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1251 1252 disconnectService(); 1253 } 1254 } else if (mPendingInstalls.size() > 0) { 1255 // There are more pending requests in queue. 1256 // Just post MCS_BOUND message to trigger processing 1257 // of next pending install. 1258 mHandler.sendEmptyMessage(MCS_BOUND); 1259 } 1260 1261 break; 1262 } 1263 case MCS_GIVE_UP: { 1264 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1265 mPendingInstalls.remove(0); 1266 break; 1267 } 1268 case SEND_PENDING_BROADCAST: { 1269 String packages[]; 1270 ArrayList<String> components[]; 1271 int size = 0; 1272 int uids[]; 1273 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1274 synchronized (mPackages) { 1275 if (mPendingBroadcasts == null) { 1276 return; 1277 } 1278 size = mPendingBroadcasts.size(); 1279 if (size <= 0) { 1280 // Nothing to be done. Just return 1281 return; 1282 } 1283 packages = new String[size]; 1284 components = new ArrayList[size]; 1285 uids = new int[size]; 1286 int i = 0; // filling out the above arrays 1287 1288 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1289 int packageUserId = mPendingBroadcasts.userIdAt(n); 1290 Iterator<Map.Entry<String, ArrayList<String>>> it 1291 = mPendingBroadcasts.packagesForUserId(packageUserId) 1292 .entrySet().iterator(); 1293 while (it.hasNext() && i < size) { 1294 Map.Entry<String, ArrayList<String>> ent = it.next(); 1295 packages[i] = ent.getKey(); 1296 components[i] = ent.getValue(); 1297 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1298 uids[i] = (ps != null) 1299 ? UserHandle.getUid(packageUserId, ps.appId) 1300 : -1; 1301 i++; 1302 } 1303 } 1304 size = i; 1305 mPendingBroadcasts.clear(); 1306 } 1307 // Send broadcasts 1308 for (int i = 0; i < size; i++) { 1309 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1310 } 1311 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1312 break; 1313 } 1314 case START_CLEANING_PACKAGE: { 1315 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1316 final String packageName = (String)msg.obj; 1317 final int userId = msg.arg1; 1318 final boolean andCode = msg.arg2 != 0; 1319 synchronized (mPackages) { 1320 if (userId == UserHandle.USER_ALL) { 1321 int[] users = sUserManager.getUserIds(); 1322 for (int user : users) { 1323 mSettings.addPackageToCleanLPw( 1324 new PackageCleanItem(user, packageName, andCode)); 1325 } 1326 } else { 1327 mSettings.addPackageToCleanLPw( 1328 new PackageCleanItem(userId, packageName, andCode)); 1329 } 1330 } 1331 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1332 startCleaningPackages(); 1333 } break; 1334 case POST_INSTALL: { 1335 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1336 PostInstallData data = mRunningInstalls.get(msg.arg1); 1337 mRunningInstalls.delete(msg.arg1); 1338 boolean deleteOld = false; 1339 1340 if (data != null) { 1341 InstallArgs args = data.args; 1342 PackageInstalledInfo res = data.res; 1343 1344 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1345 final String packageName = res.pkg.applicationInfo.packageName; 1346 res.removedInfo.sendBroadcast(false, true, false); 1347 Bundle extras = new Bundle(1); 1348 extras.putInt(Intent.EXTRA_UID, res.uid); 1349 1350 // Now that we successfully installed the package, grant runtime 1351 // permissions if requested before broadcasting the install. 1352 if ((args.installFlags 1353 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { 1354 grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(), 1355 args.installGrantPermissions); 1356 } 1357 1358 // Determine the set of users who are adding this 1359 // package for the first time vs. those who are seeing 1360 // an update. 1361 int[] firstUsers; 1362 int[] updateUsers = new int[0]; 1363 if (res.origUsers == null || res.origUsers.length == 0) { 1364 firstUsers = res.newUsers; 1365 } else { 1366 firstUsers = new int[0]; 1367 for (int i=0; i<res.newUsers.length; i++) { 1368 int user = res.newUsers[i]; 1369 boolean isNew = true; 1370 for (int j=0; j<res.origUsers.length; j++) { 1371 if (res.origUsers[j] == user) { 1372 isNew = false; 1373 break; 1374 } 1375 } 1376 if (isNew) { 1377 int[] newFirst = new int[firstUsers.length+1]; 1378 System.arraycopy(firstUsers, 0, newFirst, 0, 1379 firstUsers.length); 1380 newFirst[firstUsers.length] = user; 1381 firstUsers = newFirst; 1382 } else { 1383 int[] newUpdate = new int[updateUsers.length+1]; 1384 System.arraycopy(updateUsers, 0, newUpdate, 0, 1385 updateUsers.length); 1386 newUpdate[updateUsers.length] = user; 1387 updateUsers = newUpdate; 1388 } 1389 } 1390 } 1391 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1392 packageName, extras, null, null, firstUsers); 1393 final boolean update = res.removedInfo.removedPackage != null; 1394 if (update) { 1395 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1396 } 1397 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1398 packageName, extras, null, null, updateUsers); 1399 if (update) { 1400 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1401 packageName, extras, null, null, updateUsers); 1402 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1403 null, null, packageName, null, updateUsers); 1404 1405 // treat asec-hosted packages like removable media on upgrade 1406 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1407 if (DEBUG_INSTALL) { 1408 Slog.i(TAG, "upgrading pkg " + res.pkg 1409 + " is ASEC-hosted -> AVAILABLE"); 1410 } 1411 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1412 ArrayList<String> pkgList = new ArrayList<String>(1); 1413 pkgList.add(packageName); 1414 sendResourcesChangedBroadcast(true, true, 1415 pkgList,uidArray, null); 1416 } 1417 } 1418 if (res.removedInfo.args != null) { 1419 // Remove the replaced package's older resources safely now 1420 deleteOld = true; 1421 } 1422 1423 // If this app is a browser and it's newly-installed for some 1424 // users, clear any default-browser state in those users 1425 if (firstUsers.length > 0) { 1426 // the app's nature doesn't depend on the user, so we can just 1427 // check its browser nature in any user and generalize. 1428 if (packageIsBrowser(packageName, firstUsers[0])) { 1429 synchronized (mPackages) { 1430 for (int userId : firstUsers) { 1431 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1432 } 1433 } 1434 } 1435 } 1436 // Log current value of "unknown sources" setting 1437 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1438 getUnknownSourcesSettings()); 1439 } 1440 // Force a gc to clear up things 1441 Runtime.getRuntime().gc(); 1442 // We delete after a gc for applications on sdcard. 1443 if (deleteOld) { 1444 synchronized (mInstallLock) { 1445 res.removedInfo.args.doPostDeleteLI(true); 1446 } 1447 } 1448 if (args.observer != null) { 1449 try { 1450 Bundle extras = extrasForInstallResult(res); 1451 args.observer.onPackageInstalled(res.name, res.returnCode, 1452 res.returnMsg, extras); 1453 } catch (RemoteException e) { 1454 Slog.i(TAG, "Observer no longer exists."); 1455 } 1456 } 1457 } else { 1458 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1459 } 1460 } break; 1461 case UPDATED_MEDIA_STATUS: { 1462 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1463 boolean reportStatus = msg.arg1 == 1; 1464 boolean doGc = msg.arg2 == 1; 1465 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1466 if (doGc) { 1467 // Force a gc to clear up stale containers. 1468 Runtime.getRuntime().gc(); 1469 } 1470 if (msg.obj != null) { 1471 @SuppressWarnings("unchecked") 1472 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1473 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1474 // Unload containers 1475 unloadAllContainers(args); 1476 } 1477 if (reportStatus) { 1478 try { 1479 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1480 PackageHelper.getMountService().finishMediaUpdate(); 1481 } catch (RemoteException e) { 1482 Log.e(TAG, "MountService not running?"); 1483 } 1484 } 1485 } break; 1486 case WRITE_SETTINGS: { 1487 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1488 synchronized (mPackages) { 1489 removeMessages(WRITE_SETTINGS); 1490 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1491 mSettings.writeLPr(); 1492 mDirtyUsers.clear(); 1493 } 1494 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1495 } break; 1496 case WRITE_PACKAGE_RESTRICTIONS: { 1497 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1498 synchronized (mPackages) { 1499 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1500 for (int userId : mDirtyUsers) { 1501 mSettings.writePackageRestrictionsLPr(userId); 1502 } 1503 mDirtyUsers.clear(); 1504 } 1505 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1506 } break; 1507 case CHECK_PENDING_VERIFICATION: { 1508 final int verificationId = msg.arg1; 1509 final PackageVerificationState state = mPendingVerification.get(verificationId); 1510 1511 if ((state != null) && !state.timeoutExtended()) { 1512 final InstallArgs args = state.getInstallArgs(); 1513 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1514 1515 Slog.i(TAG, "Verification timed out for " + originUri); 1516 mPendingVerification.remove(verificationId); 1517 1518 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1519 1520 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1521 Slog.i(TAG, "Continuing with installation of " + originUri); 1522 state.setVerifierResponse(Binder.getCallingUid(), 1523 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1524 broadcastPackageVerified(verificationId, originUri, 1525 PackageManager.VERIFICATION_ALLOW, 1526 state.getInstallArgs().getUser()); 1527 try { 1528 ret = args.copyApk(mContainerService, true); 1529 } catch (RemoteException e) { 1530 Slog.e(TAG, "Could not contact the ContainerService"); 1531 } 1532 } else { 1533 broadcastPackageVerified(verificationId, originUri, 1534 PackageManager.VERIFICATION_REJECT, 1535 state.getInstallArgs().getUser()); 1536 } 1537 1538 processPendingInstall(args, ret); 1539 mHandler.sendEmptyMessage(MCS_UNBIND); 1540 } 1541 break; 1542 } 1543 case PACKAGE_VERIFIED: { 1544 final int verificationId = msg.arg1; 1545 1546 final PackageVerificationState state = mPendingVerification.get(verificationId); 1547 if (state == null) { 1548 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1549 break; 1550 } 1551 1552 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1553 1554 state.setVerifierResponse(response.callerUid, response.code); 1555 1556 if (state.isVerificationComplete()) { 1557 mPendingVerification.remove(verificationId); 1558 1559 final InstallArgs args = state.getInstallArgs(); 1560 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1561 1562 int ret; 1563 if (state.isInstallAllowed()) { 1564 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1565 broadcastPackageVerified(verificationId, originUri, 1566 response.code, state.getInstallArgs().getUser()); 1567 try { 1568 ret = args.copyApk(mContainerService, true); 1569 } catch (RemoteException e) { 1570 Slog.e(TAG, "Could not contact the ContainerService"); 1571 } 1572 } else { 1573 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1574 } 1575 1576 processPendingInstall(args, ret); 1577 1578 mHandler.sendEmptyMessage(MCS_UNBIND); 1579 } 1580 1581 break; 1582 } 1583 case START_INTENT_FILTER_VERIFICATIONS: { 1584 IFVerificationParams params = (IFVerificationParams) msg.obj; 1585 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1586 params.replacing, params.pkg); 1587 break; 1588 } 1589 case INTENT_FILTER_VERIFIED: { 1590 final int verificationId = msg.arg1; 1591 1592 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1593 verificationId); 1594 if (state == null) { 1595 Slog.w(TAG, "Invalid IntentFilter verification token " 1596 + verificationId + " received"); 1597 break; 1598 } 1599 1600 final int userId = state.getUserId(); 1601 1602 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1603 "Processing IntentFilter verification with token:" 1604 + verificationId + " and userId:" + userId); 1605 1606 final IntentFilterVerificationResponse response = 1607 (IntentFilterVerificationResponse) msg.obj; 1608 1609 state.setVerifierResponse(response.callerUid, response.code); 1610 1611 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1612 "IntentFilter verification with token:" + verificationId 1613 + " and userId:" + userId 1614 + " is settings verifier response with response code:" 1615 + response.code); 1616 1617 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1618 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1619 + response.getFailedDomainsString()); 1620 } 1621 1622 if (state.isVerificationComplete()) { 1623 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1624 } else { 1625 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1626 "IntentFilter verification with token:" + verificationId 1627 + " was not said to be complete"); 1628 } 1629 1630 break; 1631 } 1632 } 1633 } 1634 } 1635 1636 private StorageEventListener mStorageListener = new StorageEventListener() { 1637 @Override 1638 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1639 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1640 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1641 final String volumeUuid = vol.getFsUuid(); 1642 1643 // Clean up any users or apps that were removed or recreated 1644 // while this volume was missing 1645 reconcileUsers(volumeUuid); 1646 reconcileApps(volumeUuid); 1647 1648 // Clean up any install sessions that expired or were 1649 // cancelled while this volume was missing 1650 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1651 1652 loadPrivatePackages(vol); 1653 1654 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1655 unloadPrivatePackages(vol); 1656 } 1657 } 1658 1659 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1660 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1661 updateExternalMediaStatus(true, false); 1662 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1663 updateExternalMediaStatus(false, false); 1664 } 1665 } 1666 } 1667 1668 @Override 1669 public void onVolumeForgotten(String fsUuid) { 1670 if (TextUtils.isEmpty(fsUuid)) { 1671 Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1672 return; 1673 } 1674 1675 // Remove any apps installed on the forgotten volume 1676 synchronized (mPackages) { 1677 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1678 for (PackageSetting ps : packages) { 1679 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1680 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1681 UserHandle.USER_OWNER, PackageManager.DELETE_ALL_USERS); 1682 } 1683 1684 mSettings.onVolumeForgotten(fsUuid); 1685 mSettings.writeLPr(); 1686 } 1687 } 1688 }; 1689 grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId, String[] grantedPermissions)1690 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId, 1691 String[] grantedPermissions) { 1692 if (userId >= UserHandle.USER_OWNER) { 1693 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1694 } else if (userId == UserHandle.USER_ALL) { 1695 final int[] userIds; 1696 synchronized (mPackages) { 1697 userIds = UserManagerService.getInstance().getUserIds(); 1698 } 1699 for (int someUserId : userIds) { 1700 grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions); 1701 } 1702 } 1703 1704 // We could have touched GID membership, so flush out packages.list 1705 synchronized (mPackages) { 1706 mSettings.writePackageListLPr(); 1707 } 1708 } 1709 grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions)1710 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1711 String[] grantedPermissions) { 1712 SettingBase sb = (SettingBase) pkg.mExtras; 1713 if (sb == null) { 1714 return; 1715 } 1716 1717 synchronized (mPackages) { 1718 for (String permission : pkg.requestedPermissions) { 1719 BasePermission bp = mSettings.mPermissions.get(permission); 1720 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1721 && (grantedPermissions == null 1722 || ArrayUtils.contains(grantedPermissions, permission)) 1723 && (getPermissionFlags(permission, pkg.packageName, userId) 1724 & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) { 1725 grantRuntimePermission(pkg.packageName, permission, userId); 1726 } 1727 } 1728 } 1729 } 1730 extrasForInstallResult(PackageInstalledInfo res)1731 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1732 Bundle extras = null; 1733 switch (res.returnCode) { 1734 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1735 extras = new Bundle(); 1736 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1737 res.origPermission); 1738 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1739 res.origPackage); 1740 break; 1741 } 1742 case PackageManager.INSTALL_SUCCEEDED: { 1743 extras = new Bundle(); 1744 extras.putBoolean(Intent.EXTRA_REPLACING, 1745 res.removedInfo != null && res.removedInfo.removedPackage != null); 1746 break; 1747 } 1748 } 1749 return extras; 1750 } 1751 scheduleWriteSettingsLocked()1752 void scheduleWriteSettingsLocked() { 1753 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1754 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1755 } 1756 } 1757 scheduleWritePackageRestrictionsLocked(int userId)1758 void scheduleWritePackageRestrictionsLocked(int userId) { 1759 if (!sUserManager.exists(userId)) return; 1760 mDirtyUsers.add(userId); 1761 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1762 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1763 } 1764 } 1765 main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1766 public static PackageManagerService main(Context context, Installer installer, 1767 boolean factoryTest, boolean onlyCore) { 1768 PackageManagerService m = new PackageManagerService(context, installer, 1769 factoryTest, onlyCore); 1770 ServiceManager.addService("package", m); 1771 return m; 1772 } 1773 splitString(String str, char sep)1774 static String[] splitString(String str, char sep) { 1775 int count = 1; 1776 int i = 0; 1777 while ((i=str.indexOf(sep, i)) >= 0) { 1778 count++; 1779 i++; 1780 } 1781 1782 String[] res = new String[count]; 1783 i=0; 1784 count = 0; 1785 int lastI=0; 1786 while ((i=str.indexOf(sep, i)) >= 0) { 1787 res[count] = str.substring(lastI, i); 1788 count++; 1789 i++; 1790 lastI = i; 1791 } 1792 res[count] = str.substring(lastI, str.length()); 1793 return res; 1794 } 1795 getDefaultDisplayMetrics(Context context, DisplayMetrics metrics)1796 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1797 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1798 Context.DISPLAY_SERVICE); 1799 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1800 } 1801 PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1802 public PackageManagerService(Context context, Installer installer, 1803 boolean factoryTest, boolean onlyCore) { 1804 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1805 SystemClock.uptimeMillis()); 1806 1807 if (mSdkVersion <= 0) { 1808 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1809 } 1810 1811 mContext = context; 1812 mFactoryTest = factoryTest; 1813 mOnlyCore = onlyCore; 1814 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1815 mMetrics = new DisplayMetrics(); 1816 mSettings = new Settings(mPackages); 1817 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1818 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1819 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1820 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1821 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1822 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1823 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1824 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1825 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1826 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1827 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1828 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1829 1830 // TODO: add a property to control this? 1831 long dexOptLRUThresholdInMinutes; 1832 if (mLazyDexOpt) { 1833 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1834 } else { 1835 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1836 } 1837 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1838 1839 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1840 if (separateProcesses != null && separateProcesses.length() > 0) { 1841 if ("*".equals(separateProcesses)) { 1842 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1843 mSeparateProcesses = null; 1844 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1845 } else { 1846 mDefParseFlags = 0; 1847 mSeparateProcesses = separateProcesses.split(","); 1848 Slog.w(TAG, "Running with debug.separate_processes: " 1849 + separateProcesses); 1850 } 1851 } else { 1852 mDefParseFlags = 0; 1853 mSeparateProcesses = null; 1854 } 1855 1856 mInstaller = installer; 1857 mPackageDexOptimizer = new PackageDexOptimizer(this); 1858 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 1859 1860 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 1861 FgThread.get().getLooper()); 1862 1863 getDefaultDisplayMetrics(context, mMetrics); 1864 1865 SystemConfig systemConfig = SystemConfig.getInstance(); 1866 mGlobalGids = systemConfig.getGlobalGids(); 1867 mSystemPermissions = systemConfig.getSystemPermissions(); 1868 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1869 1870 synchronized (mInstallLock) { 1871 // writer 1872 synchronized (mPackages) { 1873 mHandlerThread = new ServiceThread(TAG, 1874 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1875 mHandlerThread.start(); 1876 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1877 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1878 1879 File dataDir = Environment.getDataDirectory(); 1880 mAppDataDir = new File(dataDir, "data"); 1881 mAppInstallDir = new File(dataDir, "app"); 1882 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1883 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1884 mUserAppDataDir = new File(dataDir, "user"); 1885 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1886 1887 sUserManager = new UserManagerService(context, this, 1888 mInstallLock, mPackages); 1889 1890 // Propagate permission configuration in to package manager. 1891 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1892 = systemConfig.getPermissions(); 1893 for (int i=0; i<permConfig.size(); i++) { 1894 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1895 BasePermission bp = mSettings.mPermissions.get(perm.name); 1896 if (bp == null) { 1897 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1898 mSettings.mPermissions.put(perm.name, bp); 1899 } 1900 if (perm.gids != null) { 1901 bp.setGids(perm.gids, perm.perUser); 1902 } 1903 } 1904 1905 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1906 for (int i=0; i<libConfig.size(); i++) { 1907 mSharedLibraries.put(libConfig.keyAt(i), 1908 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1909 } 1910 1911 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1912 1913 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1914 mSdkVersion, mOnlyCore); 1915 1916 String customResolverActivity = Resources.getSystem().getString( 1917 R.string.config_customResolverActivity); 1918 if (TextUtils.isEmpty(customResolverActivity)) { 1919 customResolverActivity = null; 1920 } else { 1921 mCustomResolverComponentName = ComponentName.unflattenFromString( 1922 customResolverActivity); 1923 } 1924 1925 long startTime = SystemClock.uptimeMillis(); 1926 1927 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1928 startTime); 1929 1930 // Set flag to monitor and not change apk file paths when 1931 // scanning install directories. 1932 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 1933 1934 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1935 1936 /** 1937 * Add everything in the in the boot class path to the 1938 * list of process files because dexopt will have been run 1939 * if necessary during zygote startup. 1940 */ 1941 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1942 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1943 1944 if (bootClassPath != null) { 1945 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1946 for (String element : bootClassPathElements) { 1947 alreadyDexOpted.add(element); 1948 } 1949 } else { 1950 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1951 } 1952 1953 if (systemServerClassPath != null) { 1954 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1955 for (String element : systemServerClassPathElements) { 1956 alreadyDexOpted.add(element); 1957 } 1958 } else { 1959 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 1960 } 1961 1962 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 1963 final String[] dexCodeInstructionSets = 1964 getDexCodeInstructionSets( 1965 allInstructionSets.toArray(new String[allInstructionSets.size()])); 1966 1967 /** 1968 * Ensure all external libraries have had dexopt run on them. 1969 */ 1970 if (mSharedLibraries.size() > 0) { 1971 // NOTE: For now, we're compiling these system "shared libraries" 1972 // (and framework jars) into all available architectures. It's possible 1973 // to compile them only when we come across an app that uses them (there's 1974 // already logic for that in scanPackageLI) but that adds some complexity. 1975 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1976 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1977 final String lib = libEntry.path; 1978 if (lib == null) { 1979 continue; 1980 } 1981 1982 try { 1983 int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); 1984 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1985 alreadyDexOpted.add(lib); 1986 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false); 1987 } 1988 } catch (FileNotFoundException e) { 1989 Slog.w(TAG, "Library not found: " + lib); 1990 } catch (IOException e) { 1991 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1992 + e.getMessage()); 1993 } 1994 } 1995 } 1996 } 1997 1998 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1999 2000 // Gross hack for now: we know this file doesn't contain any 2001 // code, so don't dexopt it to avoid the resulting log spew. 2002 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 2003 2004 // Gross hack for now: we know this file is only part of 2005 // the boot class path for art, so don't dexopt it to 2006 // avoid the resulting log spew. 2007 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 2008 2009 /** 2010 * There are a number of commands implemented in Java, which 2011 * we currently need to do the dexopt on so that they can be 2012 * run from a non-root shell. 2013 */ 2014 String[] frameworkFiles = frameworkDir.list(); 2015 if (frameworkFiles != null) { 2016 // TODO: We could compile these only for the most preferred ABI. We should 2017 // first double check that the dex files for these commands are not referenced 2018 // by other system apps. 2019 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2020 for (int i=0; i<frameworkFiles.length; i++) { 2021 File libPath = new File(frameworkDir, frameworkFiles[i]); 2022 String path = libPath.getPath(); 2023 // Skip the file if we already did it. 2024 if (alreadyDexOpted.contains(path)) { 2025 continue; 2026 } 2027 // Skip the file if it is not a type we want to dexopt. 2028 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 2029 continue; 2030 } 2031 try { 2032 int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); 2033 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2034 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false); 2035 } 2036 } catch (FileNotFoundException e) { 2037 Slog.w(TAG, "Jar not found: " + path); 2038 } catch (IOException e) { 2039 Slog.w(TAG, "Exception reading jar: " + path, e); 2040 } 2041 } 2042 } 2043 } 2044 2045 final VersionInfo ver = mSettings.getInternalVersion(); 2046 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2047 // when upgrading from pre-M, promote system app permissions from install to runtime 2048 mPromoteSystemApps = 2049 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2050 2051 // save off the names of pre-existing system packages prior to scanning; we don't 2052 // want to automatically grant runtime permissions for new system apps 2053 if (mPromoteSystemApps) { 2054 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2055 while (pkgSettingIter.hasNext()) { 2056 PackageSetting ps = pkgSettingIter.next(); 2057 if (isSystemApp(ps)) { 2058 mExistingSystemPackages.add(ps.name); 2059 } 2060 } 2061 } 2062 2063 // Collect vendor overlay packages. 2064 // (Do this before scanning any apps.) 2065 // For security and version matching reason, only consider 2066 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2067 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2068 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2069 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2070 2071 // Find base frameworks (resource packages without code). 2072 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2073 | PackageParser.PARSE_IS_SYSTEM_DIR 2074 | PackageParser.PARSE_IS_PRIVILEGED, 2075 scanFlags | SCAN_NO_DEX, 0); 2076 2077 // Collected privileged system packages. 2078 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2079 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2080 | PackageParser.PARSE_IS_SYSTEM_DIR 2081 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2082 2083 // Collect ordinary system packages. 2084 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2085 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2086 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2087 2088 // Collect all vendor packages. 2089 File vendorAppDir = new File("/vendor/app"); 2090 try { 2091 vendorAppDir = vendorAppDir.getCanonicalFile(); 2092 } catch (IOException e) { 2093 // failed to look up canonical path, continue with original one 2094 } 2095 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2096 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2097 2098 // Collect all OEM packages. 2099 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2100 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2101 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2102 2103 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 2104 mInstaller.moveFiles(); 2105 2106 // Prune any system packages that no longer exist. 2107 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2108 if (!mOnlyCore) { 2109 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2110 while (psit.hasNext()) { 2111 PackageSetting ps = psit.next(); 2112 2113 /* 2114 * If this is not a system app, it can't be a 2115 * disable system app. 2116 */ 2117 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2118 continue; 2119 } 2120 2121 /* 2122 * If the package is scanned, it's not erased. 2123 */ 2124 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2125 if (scannedPkg != null) { 2126 /* 2127 * If the system app is both scanned and in the 2128 * disabled packages list, then it must have been 2129 * added via OTA. Remove it from the currently 2130 * scanned package so the previously user-installed 2131 * application can be scanned. 2132 */ 2133 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2134 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2135 + ps.name + "; removing system app. Last known codePath=" 2136 + ps.codePathString + ", installStatus=" + ps.installStatus 2137 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2138 + scannedPkg.mVersionCode); 2139 removePackageLI(ps, true); 2140 mExpectingBetter.put(ps.name, ps.codePath); 2141 } 2142 2143 continue; 2144 } 2145 2146 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2147 psit.remove(); 2148 logCriticalInfo(Log.WARN, "System package " + ps.name 2149 + " no longer exists; wiping its data"); 2150 removeDataDirsLI(null, ps.name); 2151 } else { 2152 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2153 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2154 possiblyDeletedUpdatedSystemApps.add(ps.name); 2155 } 2156 } 2157 } 2158 } 2159 2160 //look for any incomplete package installations 2161 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2162 //clean up list 2163 for(int i = 0; i < deletePkgsList.size(); i++) { 2164 //clean up here 2165 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2166 } 2167 //delete tmp files 2168 deleteTempPackageFiles(); 2169 2170 // Remove any shared userIDs that have no associated packages 2171 mSettings.pruneSharedUsersLPw(); 2172 2173 if (!mOnlyCore) { 2174 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2175 SystemClock.uptimeMillis()); 2176 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2177 2178 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2179 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2180 2181 /** 2182 * Remove disable package settings for any updated system 2183 * apps that were removed via an OTA. If they're not a 2184 * previously-updated app, remove them completely. 2185 * Otherwise, just revoke their system-level permissions. 2186 */ 2187 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2188 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2189 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2190 2191 String msg; 2192 if (deletedPkg == null) { 2193 msg = "Updated system package " + deletedAppName 2194 + " no longer exists; wiping its data"; 2195 removeDataDirsLI(null, deletedAppName); 2196 } else { 2197 msg = "Updated system app + " + deletedAppName 2198 + " no longer present; removing system privileges for " 2199 + deletedAppName; 2200 2201 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2202 2203 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2204 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2205 } 2206 logCriticalInfo(Log.WARN, msg); 2207 } 2208 2209 /** 2210 * Make sure all system apps that we expected to appear on 2211 * the userdata partition actually showed up. If they never 2212 * appeared, crawl back and revive the system version. 2213 */ 2214 for (int i = 0; i < mExpectingBetter.size(); i++) { 2215 final String packageName = mExpectingBetter.keyAt(i); 2216 if (!mPackages.containsKey(packageName)) { 2217 final File scanFile = mExpectingBetter.valueAt(i); 2218 2219 logCriticalInfo(Log.WARN, "Expected better " + packageName 2220 + " but never showed up; reverting to system"); 2221 2222 final int reparseFlags; 2223 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2224 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2225 | PackageParser.PARSE_IS_SYSTEM_DIR 2226 | PackageParser.PARSE_IS_PRIVILEGED; 2227 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2228 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2229 | PackageParser.PARSE_IS_SYSTEM_DIR; 2230 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2231 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2232 | PackageParser.PARSE_IS_SYSTEM_DIR; 2233 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2234 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2235 | PackageParser.PARSE_IS_SYSTEM_DIR; 2236 } else { 2237 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2238 continue; 2239 } 2240 2241 mSettings.enableSystemPackageLPw(packageName); 2242 2243 try { 2244 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null); 2245 } catch (PackageManagerException e) { 2246 Slog.e(TAG, "Failed to parse original system package: " 2247 + e.getMessage()); 2248 } 2249 } 2250 } 2251 } 2252 mExpectingBetter.clear(); 2253 2254 // Now that we know all of the shared libraries, update all clients to have 2255 // the correct library paths. 2256 updateAllSharedLibrariesLPw(); 2257 2258 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2259 // NOTE: We ignore potential failures here during a system scan (like 2260 // the rest of the commands above) because there's precious little we 2261 // can do about it. A settings error is reported, though. 2262 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2263 false /* force dexopt */, false /* defer dexopt */, 2264 false /* boot complete */); 2265 } 2266 2267 // Now that we know all the packages we are keeping, 2268 // read and update their last usage times. 2269 mPackageUsage.readLP(); 2270 2271 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2272 SystemClock.uptimeMillis()); 2273 Slog.i(TAG, "Time to scan packages: " 2274 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2275 + " seconds"); 2276 2277 // If the platform SDK has changed since the last time we booted, 2278 // we need to re-grant app permission to catch any new ones that 2279 // appear. This is really a hack, and means that apps can in some 2280 // cases get permissions that the user didn't initially explicitly 2281 // allow... it would be nice to have some better way to handle 2282 // this situation. 2283 int updateFlags = UPDATE_PERMISSIONS_ALL; 2284 if (ver.sdkVersion != mSdkVersion) { 2285 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2286 + mSdkVersion + "; regranting permissions for internal storage"); 2287 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2288 } 2289 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2290 ver.sdkVersion = mSdkVersion; 2291 2292 // If this is the first boot or an update from pre-M, and it is a normal 2293 // boot, then we need to initialize the default preferred apps across 2294 // all defined users. 2295 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { 2296 for (UserInfo user : sUserManager.getUsers(true)) { 2297 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2298 applyFactoryDefaultBrowserLPw(user.id); 2299 primeDomainVerificationsLPw(user.id); 2300 } 2301 } 2302 2303 // If this is first boot after an OTA, and a normal boot, then 2304 // we need to clear code cache directories. 2305 if (mIsUpgrade && !onlyCore) { 2306 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2307 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2308 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2309 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2310 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2311 } 2312 } 2313 ver.fingerprint = Build.FINGERPRINT; 2314 } 2315 2316 checkDefaultBrowser(); 2317 2318 // clear only after permissions and other defaults have been updated 2319 mExistingSystemPackages.clear(); 2320 mPromoteSystemApps = false; 2321 2322 // All the changes are done during package scanning. 2323 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2324 2325 // can downgrade to reader 2326 mSettings.writeLPr(); 2327 2328 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2329 SystemClock.uptimeMillis()); 2330 2331 mRequiredVerifierPackage = getRequiredVerifierLPr(); 2332 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2333 2334 mInstallerService = new PackageInstallerService(context, this); 2335 2336 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2337 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2338 mIntentFilterVerifierComponent); 2339 2340 } // synchronized (mPackages) 2341 } // synchronized (mInstallLock) 2342 2343 // Now after opening every single application zip, make sure they 2344 // are all flushed. Not really needed, but keeps things nice and 2345 // tidy. 2346 Runtime.getRuntime().gc(); 2347 2348 // Expose private service for system components to use. 2349 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2350 } 2351 2352 @Override isFirstBoot()2353 public boolean isFirstBoot() { 2354 return !mRestoredSettings; 2355 } 2356 2357 @Override isOnlyCoreApps()2358 public boolean isOnlyCoreApps() { 2359 return mOnlyCore; 2360 } 2361 2362 @Override isUpgrade()2363 public boolean isUpgrade() { 2364 return mIsUpgrade; 2365 } 2366 getRequiredVerifierLPr()2367 private String getRequiredVerifierLPr() { 2368 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2369 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2370 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 2371 2372 String requiredVerifier = null; 2373 2374 final int N = receivers.size(); 2375 for (int i = 0; i < N; i++) { 2376 final ResolveInfo info = receivers.get(i); 2377 2378 if (info.activityInfo == null) { 2379 continue; 2380 } 2381 2382 final String packageName = info.activityInfo.packageName; 2383 2384 if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 2385 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2386 continue; 2387 } 2388 2389 if (requiredVerifier != null) { 2390 throw new RuntimeException("There can be only one required verifier"); 2391 } 2392 2393 requiredVerifier = packageName; 2394 } 2395 2396 return requiredVerifier; 2397 } 2398 getRequiredInstallerLPr()2399 private String getRequiredInstallerLPr() { 2400 Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2401 installerIntent.addCategory(Intent.CATEGORY_DEFAULT); 2402 installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2403 2404 final List<ResolveInfo> installers = queryIntentActivities(installerIntent, 2405 PACKAGE_MIME_TYPE, 0, 0); 2406 2407 String requiredInstaller = null; 2408 2409 final int N = installers.size(); 2410 for (int i = 0; i < N; i++) { 2411 final ResolveInfo info = installers.get(i); 2412 final String packageName = info.activityInfo.packageName; 2413 2414 if (!info.activityInfo.applicationInfo.isSystemApp()) { 2415 continue; 2416 } 2417 2418 if (requiredInstaller != null) { 2419 throw new RuntimeException("There must be one required installer"); 2420 } 2421 2422 requiredInstaller = packageName; 2423 } 2424 2425 if (requiredInstaller == null) { 2426 throw new RuntimeException("There must be one required installer"); 2427 } 2428 2429 return requiredInstaller; 2430 } 2431 getIntentFilterVerifierComponentNameLPr()2432 private ComponentName getIntentFilterVerifierComponentNameLPr() { 2433 final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2434 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2435 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */); 2436 2437 ComponentName verifierComponentName = null; 2438 2439 int priority = -1000; 2440 final int N = receivers.size(); 2441 for (int i = 0; i < N; i++) { 2442 final ResolveInfo info = receivers.get(i); 2443 2444 if (info.activityInfo == null) { 2445 continue; 2446 } 2447 2448 final String packageName = info.activityInfo.packageName; 2449 2450 final PackageSetting ps = mSettings.mPackages.get(packageName); 2451 if (ps == null) { 2452 continue; 2453 } 2454 2455 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2456 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2457 continue; 2458 } 2459 2460 // Select the IntentFilterVerifier with the highest priority 2461 if (priority < info.priority) { 2462 priority = info.priority; 2463 verifierComponentName = new ComponentName(packageName, info.activityInfo.name); 2464 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Selecting IntentFilterVerifier: " 2465 + verifierComponentName + " with priority: " + info.priority); 2466 } 2467 } 2468 2469 return verifierComponentName; 2470 } 2471 primeDomainVerificationsLPw(int userId)2472 private void primeDomainVerificationsLPw(int userId) { 2473 if (DEBUG_DOMAIN_VERIFICATION) { 2474 Slog.d(TAG, "Priming domain verifications in user " + userId); 2475 } 2476 2477 SystemConfig systemConfig = SystemConfig.getInstance(); 2478 ArraySet<String> packages = systemConfig.getLinkedApps(); 2479 ArraySet<String> domains = new ArraySet<String>(); 2480 2481 for (String packageName : packages) { 2482 PackageParser.Package pkg = mPackages.get(packageName); 2483 if (pkg != null) { 2484 if (!pkg.isSystemApp()) { 2485 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2486 continue; 2487 } 2488 2489 domains.clear(); 2490 for (PackageParser.Activity a : pkg.activities) { 2491 for (ActivityIntentInfo filter : a.intents) { 2492 if (hasValidDomains(filter)) { 2493 domains.addAll(filter.getHostsList()); 2494 } 2495 } 2496 } 2497 2498 if (domains.size() > 0) { 2499 if (DEBUG_DOMAIN_VERIFICATION) { 2500 Slog.v(TAG, " + " + packageName); 2501 } 2502 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2503 // state w.r.t. the formal app-linkage "no verification attempted" state; 2504 // and then 'always' in the per-user state actually used for intent resolution. 2505 final IntentFilterVerificationInfo ivi; 2506 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2507 new ArrayList<String>(domains)); 2508 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2509 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2510 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2511 } else { 2512 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2513 + "' does not handle web links"); 2514 } 2515 } else { 2516 Slog.w(TAG, "Unknown package '" + packageName + "' in sysconfig <app-link>"); 2517 } 2518 } 2519 2520 scheduleWritePackageRestrictionsLocked(userId); 2521 scheduleWriteSettingsLocked(); 2522 } 2523 applyFactoryDefaultBrowserLPw(int userId)2524 private void applyFactoryDefaultBrowserLPw(int userId) { 2525 // The default browser app's package name is stored in a string resource, 2526 // with a product-specific overlay used for vendor customization. 2527 String browserPkg = mContext.getResources().getString( 2528 com.android.internal.R.string.default_browser); 2529 if (!TextUtils.isEmpty(browserPkg)) { 2530 // non-empty string => required to be a known package 2531 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2532 if (ps == null) { 2533 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2534 browserPkg = null; 2535 } else { 2536 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2537 } 2538 } 2539 2540 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2541 // default. If there's more than one, just leave everything alone. 2542 if (browserPkg == null) { 2543 calculateDefaultBrowserLPw(userId); 2544 } 2545 } 2546 calculateDefaultBrowserLPw(int userId)2547 private void calculateDefaultBrowserLPw(int userId) { 2548 List<String> allBrowsers = resolveAllBrowserApps(userId); 2549 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2550 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2551 } 2552 resolveAllBrowserApps(int userId)2553 private List<String> resolveAllBrowserApps(int userId) { 2554 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2555 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2556 PackageManager.MATCH_ALL, userId); 2557 2558 final int count = list.size(); 2559 List<String> result = new ArrayList<String>(count); 2560 for (int i=0; i<count; i++) { 2561 ResolveInfo info = list.get(i); 2562 if (info.activityInfo == null 2563 || !info.handleAllWebDataURI 2564 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2565 || result.contains(info.activityInfo.packageName)) { 2566 continue; 2567 } 2568 result.add(info.activityInfo.packageName); 2569 } 2570 2571 return result; 2572 } 2573 packageIsBrowser(String packageName, int userId)2574 private boolean packageIsBrowser(String packageName, int userId) { 2575 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2576 PackageManager.MATCH_ALL, userId); 2577 final int N = list.size(); 2578 for (int i = 0; i < N; i++) { 2579 ResolveInfo info = list.get(i); 2580 if (packageName.equals(info.activityInfo.packageName)) { 2581 return true; 2582 } 2583 } 2584 return false; 2585 } 2586 checkDefaultBrowser()2587 private void checkDefaultBrowser() { 2588 final int myUserId = UserHandle.myUserId(); 2589 final String packageName = getDefaultBrowserPackageName(myUserId); 2590 if (packageName != null) { 2591 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2592 if (info == null) { 2593 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2594 synchronized (mPackages) { 2595 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2596 } 2597 } 2598 } 2599 } 2600 2601 @Override onTransact(int code, Parcel data, Parcel reply, int flags)2602 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2603 throws RemoteException { 2604 try { 2605 return super.onTransact(code, data, reply, flags); 2606 } catch (RuntimeException e) { 2607 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2608 Slog.wtf(TAG, "Package Manager Crash", e); 2609 } 2610 throw e; 2611 } 2612 } 2613 cleanupInstallFailedPackage(PackageSetting ps)2614 void cleanupInstallFailedPackage(PackageSetting ps) { 2615 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2616 2617 removeDataDirsLI(ps.volumeUuid, ps.name); 2618 if (ps.codePath != null) { 2619 if (ps.codePath.isDirectory()) { 2620 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath()); 2621 } else { 2622 ps.codePath.delete(); 2623 } 2624 } 2625 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2626 if (ps.resourcePath.isDirectory()) { 2627 FileUtils.deleteContents(ps.resourcePath); 2628 } 2629 ps.resourcePath.delete(); 2630 } 2631 mSettings.removePackageLPw(ps.name); 2632 } 2633 appendInts(int[] cur, int[] add)2634 static int[] appendInts(int[] cur, int[] add) { 2635 if (add == null) return cur; 2636 if (cur == null) return add; 2637 final int N = add.length; 2638 for (int i=0; i<N; i++) { 2639 cur = appendInt(cur, add[i]); 2640 } 2641 return cur; 2642 } 2643 generatePackageInfo(PackageParser.Package p, int flags, int userId)2644 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2645 if (!sUserManager.exists(userId)) return null; 2646 final PackageSetting ps = (PackageSetting) p.mExtras; 2647 if (ps == null) { 2648 return null; 2649 } 2650 2651 final PermissionsState permissionsState = ps.getPermissionsState(); 2652 2653 final int[] gids = permissionsState.computeGids(userId); 2654 final Set<String> permissions = permissionsState.getPermissions(userId); 2655 final PackageUserState state = ps.readUserState(userId); 2656 2657 return PackageParser.generatePackageInfo(p, gids, flags, 2658 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2659 } 2660 2661 @Override isPackageFrozen(String packageName)2662 public boolean isPackageFrozen(String packageName) { 2663 synchronized (mPackages) { 2664 final PackageSetting ps = mSettings.mPackages.get(packageName); 2665 if (ps != null) { 2666 return ps.frozen; 2667 } 2668 } 2669 Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen"); 2670 return true; 2671 } 2672 2673 @Override isPackageAvailable(String packageName, int userId)2674 public boolean isPackageAvailable(String packageName, int userId) { 2675 if (!sUserManager.exists(userId)) return false; 2676 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 2677 synchronized (mPackages) { 2678 PackageParser.Package p = mPackages.get(packageName); 2679 if (p != null) { 2680 final PackageSetting ps = (PackageSetting) p.mExtras; 2681 if (ps != null) { 2682 final PackageUserState state = ps.readUserState(userId); 2683 if (state != null) { 2684 return PackageParser.isAvailable(state); 2685 } 2686 } 2687 } 2688 } 2689 return false; 2690 } 2691 2692 @Override getPackageInfo(String packageName, int flags, int userId)2693 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2694 if (!sUserManager.exists(userId)) return null; 2695 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 2696 // reader 2697 synchronized (mPackages) { 2698 PackageParser.Package p = mPackages.get(packageName); 2699 if (DEBUG_PACKAGE_INFO) 2700 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2701 if (p != null) { 2702 return generatePackageInfo(p, flags, userId); 2703 } 2704 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2705 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2706 } 2707 } 2708 return null; 2709 } 2710 2711 @Override currentToCanonicalPackageNames(String[] names)2712 public String[] currentToCanonicalPackageNames(String[] names) { 2713 String[] out = new String[names.length]; 2714 // reader 2715 synchronized (mPackages) { 2716 for (int i=names.length-1; i>=0; i--) { 2717 PackageSetting ps = mSettings.mPackages.get(names[i]); 2718 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2719 } 2720 } 2721 return out; 2722 } 2723 2724 @Override canonicalToCurrentPackageNames(String[] names)2725 public String[] canonicalToCurrentPackageNames(String[] names) { 2726 String[] out = new String[names.length]; 2727 // reader 2728 synchronized (mPackages) { 2729 for (int i=names.length-1; i>=0; i--) { 2730 String cur = mSettings.mRenamedPackages.get(names[i]); 2731 out[i] = cur != null ? cur : names[i]; 2732 } 2733 } 2734 return out; 2735 } 2736 2737 @Override getPackageUid(String packageName, int userId)2738 public int getPackageUid(String packageName, int userId) { 2739 return getPackageUidEtc(packageName, 0, userId); 2740 } 2741 2742 @Override getPackageUidEtc(String packageName, int flags, int userId)2743 public int getPackageUidEtc(String packageName, int flags, int userId) { 2744 if (!sUserManager.exists(userId)) return -1; 2745 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 2746 2747 // reader 2748 synchronized (mPackages) { 2749 final PackageParser.Package p = mPackages.get(packageName); 2750 if (p != null) { 2751 return UserHandle.getUid(userId, p.applicationInfo.uid); 2752 } 2753 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2754 final PackageSetting ps = mSettings.mPackages.get(packageName); 2755 if (ps != null) { 2756 return UserHandle.getUid(userId, ps.appId); 2757 } 2758 } 2759 } 2760 2761 return -1; 2762 } 2763 2764 @Override getPackageGids(String packageName, int userId)2765 public int[] getPackageGids(String packageName, int userId) { 2766 return getPackageGidsEtc(packageName, 0, userId); 2767 } 2768 2769 @Override getPackageGidsEtc(String packageName, int flags, int userId)2770 public int[] getPackageGidsEtc(String packageName, int flags, int userId) { 2771 if (!sUserManager.exists(userId)) { 2772 return null; 2773 } 2774 2775 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 2776 "getPackageGids"); 2777 2778 // reader 2779 synchronized (mPackages) { 2780 final PackageParser.Package p = mPackages.get(packageName); 2781 if (p != null) { 2782 PackageSetting ps = (PackageSetting) p.mExtras; 2783 return ps.getPermissionsState().computeGids(userId); 2784 } 2785 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2786 final PackageSetting ps = mSettings.mPackages.get(packageName); 2787 if (ps != null) { 2788 return ps.getPermissionsState().computeGids(userId); 2789 } 2790 } 2791 } 2792 2793 return null; 2794 } 2795 generatePermissionInfo( BasePermission bp, int flags)2796 static PermissionInfo generatePermissionInfo( 2797 BasePermission bp, int flags) { 2798 if (bp.perm != null) { 2799 return PackageParser.generatePermissionInfo(bp.perm, flags); 2800 } 2801 PermissionInfo pi = new PermissionInfo(); 2802 pi.name = bp.name; 2803 pi.packageName = bp.sourcePackage; 2804 pi.nonLocalizedLabel = bp.name; 2805 pi.protectionLevel = bp.protectionLevel; 2806 return pi; 2807 } 2808 2809 @Override getPermissionInfo(String name, int flags)2810 public PermissionInfo getPermissionInfo(String name, int flags) { 2811 // reader 2812 synchronized (mPackages) { 2813 final BasePermission p = mSettings.mPermissions.get(name); 2814 if (p != null) { 2815 return generatePermissionInfo(p, flags); 2816 } 2817 return null; 2818 } 2819 } 2820 2821 @Override queryPermissionsByGroup(String group, int flags)2822 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2823 // reader 2824 synchronized (mPackages) { 2825 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2826 for (BasePermission p : mSettings.mPermissions.values()) { 2827 if (group == null) { 2828 if (p.perm == null || p.perm.info.group == null) { 2829 out.add(generatePermissionInfo(p, flags)); 2830 } 2831 } else { 2832 if (p.perm != null && group.equals(p.perm.info.group)) { 2833 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2834 } 2835 } 2836 } 2837 2838 if (out.size() > 0) { 2839 return out; 2840 } 2841 return mPermissionGroups.containsKey(group) ? out : null; 2842 } 2843 } 2844 2845 @Override getPermissionGroupInfo(String name, int flags)2846 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2847 // reader 2848 synchronized (mPackages) { 2849 return PackageParser.generatePermissionGroupInfo( 2850 mPermissionGroups.get(name), flags); 2851 } 2852 } 2853 2854 @Override getAllPermissionGroups(int flags)2855 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2856 // reader 2857 synchronized (mPackages) { 2858 final int N = mPermissionGroups.size(); 2859 ArrayList<PermissionGroupInfo> out 2860 = new ArrayList<PermissionGroupInfo>(N); 2861 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2862 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2863 } 2864 return out; 2865 } 2866 } 2867 generateApplicationInfoFromSettingsLPw(String packageName, int flags, int userId)2868 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2869 int userId) { 2870 if (!sUserManager.exists(userId)) return null; 2871 PackageSetting ps = mSettings.mPackages.get(packageName); 2872 if (ps != null) { 2873 if (ps.pkg == null) { 2874 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2875 flags, userId); 2876 if (pInfo != null) { 2877 return pInfo.applicationInfo; 2878 } 2879 return null; 2880 } 2881 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2882 ps.readUserState(userId), userId); 2883 } 2884 return null; 2885 } 2886 generatePackageInfoFromSettingsLPw(String packageName, int flags, int userId)2887 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2888 int userId) { 2889 if (!sUserManager.exists(userId)) return null; 2890 PackageSetting ps = mSettings.mPackages.get(packageName); 2891 if (ps != null) { 2892 PackageParser.Package pkg = ps.pkg; 2893 if (pkg == null) { 2894 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2895 return null; 2896 } 2897 // Only data remains, so we aren't worried about code paths 2898 pkg = new PackageParser.Package(packageName); 2899 pkg.applicationInfo.packageName = packageName; 2900 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2901 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 2902 pkg.applicationInfo.dataDir = Environment 2903 .getDataUserPackageDirectory(ps.volumeUuid, userId, packageName) 2904 .getAbsolutePath(); 2905 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2906 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2907 } 2908 return generatePackageInfo(pkg, flags, userId); 2909 } 2910 return null; 2911 } 2912 2913 @Override getApplicationInfo(String packageName, int flags, int userId)2914 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2915 if (!sUserManager.exists(userId)) return null; 2916 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2917 // writer 2918 synchronized (mPackages) { 2919 PackageParser.Package p = mPackages.get(packageName); 2920 if (DEBUG_PACKAGE_INFO) Log.v( 2921 TAG, "getApplicationInfo " + packageName 2922 + ": " + p); 2923 if (p != null) { 2924 PackageSetting ps = mSettings.mPackages.get(packageName); 2925 if (ps == null) return null; 2926 // Note: isEnabledLP() does not apply here - always return info 2927 return PackageParser.generateApplicationInfo( 2928 p, flags, ps.readUserState(userId), userId); 2929 } 2930 if ("android".equals(packageName)||"system".equals(packageName)) { 2931 return mAndroidApplication; 2932 } 2933 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2934 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2935 } 2936 } 2937 return null; 2938 } 2939 2940 @Override freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, final IPackageDataObserver observer)2941 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 2942 final IPackageDataObserver observer) { 2943 mContext.enforceCallingOrSelfPermission( 2944 android.Manifest.permission.CLEAR_APP_CACHE, null); 2945 // Queue up an async operation since clearing cache may take a little while. 2946 mHandler.post(new Runnable() { 2947 public void run() { 2948 mHandler.removeCallbacks(this); 2949 int retCode = -1; 2950 synchronized (mInstallLock) { 2951 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2952 if (retCode < 0) { 2953 Slog.w(TAG, "Couldn't clear application caches"); 2954 } 2955 } 2956 if (observer != null) { 2957 try { 2958 observer.onRemoveCompleted(null, (retCode >= 0)); 2959 } catch (RemoteException e) { 2960 Slog.w(TAG, "RemoveException when invoking call back"); 2961 } 2962 } 2963 } 2964 }); 2965 } 2966 2967 @Override freeStorage(final String volumeUuid, final long freeStorageSize, final IntentSender pi)2968 public void freeStorage(final String volumeUuid, final long freeStorageSize, 2969 final IntentSender pi) { 2970 mContext.enforceCallingOrSelfPermission( 2971 android.Manifest.permission.CLEAR_APP_CACHE, null); 2972 // Queue up an async operation since clearing cache may take a little while. 2973 mHandler.post(new Runnable() { 2974 public void run() { 2975 mHandler.removeCallbacks(this); 2976 int retCode = -1; 2977 synchronized (mInstallLock) { 2978 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2979 if (retCode < 0) { 2980 Slog.w(TAG, "Couldn't clear application caches"); 2981 } 2982 } 2983 if(pi != null) { 2984 try { 2985 // Callback via pending intent 2986 int code = (retCode >= 0) ? 1 : 0; 2987 pi.sendIntent(null, code, null, 2988 null, null); 2989 } catch (SendIntentException e1) { 2990 Slog.i(TAG, "Failed to send pending intent"); 2991 } 2992 } 2993 } 2994 }); 2995 } 2996 freeStorage(String volumeUuid, long freeStorageSize)2997 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 2998 synchronized (mInstallLock) { 2999 if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) { 3000 throw new IOException("Failed to free enough space"); 3001 } 3002 } 3003 } 3004 3005 @Override getActivityInfo(ComponentName component, int flags, int userId)3006 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3007 if (!sUserManager.exists(userId)) return null; 3008 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 3009 synchronized (mPackages) { 3010 PackageParser.Activity a = mActivities.mActivities.get(component); 3011 3012 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3013 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 3014 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3015 if (ps == null) return null; 3016 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3017 userId); 3018 } 3019 if (mResolveComponentName.equals(component)) { 3020 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3021 new PackageUserState(), userId); 3022 } 3023 } 3024 return null; 3025 } 3026 3027 @Override activitySupportsIntent(ComponentName component, Intent intent, String resolvedType)3028 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3029 String resolvedType) { 3030 synchronized (mPackages) { 3031 if (component.equals(mResolveComponentName)) { 3032 // The resolver supports EVERYTHING! 3033 return true; 3034 } 3035 PackageParser.Activity a = mActivities.mActivities.get(component); 3036 if (a == null) { 3037 return false; 3038 } 3039 for (int i=0; i<a.intents.size(); i++) { 3040 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3041 intent.getData(), intent.getCategories(), TAG) >= 0) { 3042 return true; 3043 } 3044 } 3045 return false; 3046 } 3047 } 3048 3049 @Override getReceiverInfo(ComponentName component, int flags, int userId)3050 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3051 if (!sUserManager.exists(userId)) return null; 3052 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 3053 synchronized (mPackages) { 3054 PackageParser.Activity a = mReceivers.mActivities.get(component); 3055 if (DEBUG_PACKAGE_INFO) Log.v( 3056 TAG, "getReceiverInfo " + component + ": " + a); 3057 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 3058 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3059 if (ps == null) return null; 3060 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3061 userId); 3062 } 3063 } 3064 return null; 3065 } 3066 3067 @Override getServiceInfo(ComponentName component, int flags, int userId)3068 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3069 if (!sUserManager.exists(userId)) return null; 3070 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 3071 synchronized (mPackages) { 3072 PackageParser.Service s = mServices.mServices.get(component); 3073 if (DEBUG_PACKAGE_INFO) Log.v( 3074 TAG, "getServiceInfo " + component + ": " + s); 3075 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 3076 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3077 if (ps == null) return null; 3078 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3079 userId); 3080 } 3081 } 3082 return null; 3083 } 3084 3085 @Override getProviderInfo(ComponentName component, int flags, int userId)3086 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3087 if (!sUserManager.exists(userId)) return null; 3088 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 3089 synchronized (mPackages) { 3090 PackageParser.Provider p = mProviders.mProviders.get(component); 3091 if (DEBUG_PACKAGE_INFO) Log.v( 3092 TAG, "getProviderInfo " + component + ": " + p); 3093 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 3094 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3095 if (ps == null) return null; 3096 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3097 userId); 3098 } 3099 } 3100 return null; 3101 } 3102 3103 @Override getSystemSharedLibraryNames()3104 public String[] getSystemSharedLibraryNames() { 3105 Set<String> libSet; 3106 synchronized (mPackages) { 3107 libSet = mSharedLibraries.keySet(); 3108 int size = libSet.size(); 3109 if (size > 0) { 3110 String[] libs = new String[size]; 3111 libSet.toArray(libs); 3112 return libs; 3113 } 3114 } 3115 return null; 3116 } 3117 3118 /** 3119 * @hide 3120 */ findSharedNonSystemLibrary(String libName)3121 PackageParser.Package findSharedNonSystemLibrary(String libName) { 3122 synchronized (mPackages) { 3123 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 3124 if (lib != null && lib.apk != null) { 3125 return mPackages.get(lib.apk); 3126 } 3127 } 3128 return null; 3129 } 3130 3131 @Override getSystemAvailableFeatures()3132 public FeatureInfo[] getSystemAvailableFeatures() { 3133 Collection<FeatureInfo> featSet; 3134 synchronized (mPackages) { 3135 featSet = mAvailableFeatures.values(); 3136 int size = featSet.size(); 3137 if (size > 0) { 3138 FeatureInfo[] features = new FeatureInfo[size+1]; 3139 featSet.toArray(features); 3140 FeatureInfo fi = new FeatureInfo(); 3141 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3142 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3143 features[size] = fi; 3144 return features; 3145 } 3146 } 3147 return null; 3148 } 3149 3150 @Override hasSystemFeature(String name)3151 public boolean hasSystemFeature(String name) { 3152 synchronized (mPackages) { 3153 return mAvailableFeatures.containsKey(name); 3154 } 3155 } 3156 checkValidCaller(int uid, int userId)3157 private void checkValidCaller(int uid, int userId) { 3158 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 3159 return; 3160 3161 throw new SecurityException("Caller uid=" + uid 3162 + " is not privileged to communicate with user=" + userId); 3163 } 3164 3165 @Override checkPermission(String permName, String pkgName, int userId)3166 public int checkPermission(String permName, String pkgName, int userId) { 3167 if (!sUserManager.exists(userId)) { 3168 return PackageManager.PERMISSION_DENIED; 3169 } 3170 3171 synchronized (mPackages) { 3172 final PackageParser.Package p = mPackages.get(pkgName); 3173 if (p != null && p.mExtras != null) { 3174 final PackageSetting ps = (PackageSetting) p.mExtras; 3175 final PermissionsState permissionsState = ps.getPermissionsState(); 3176 if (permissionsState.hasPermission(permName, userId)) { 3177 return PackageManager.PERMISSION_GRANTED; 3178 } 3179 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3180 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3181 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3182 return PackageManager.PERMISSION_GRANTED; 3183 } 3184 } 3185 } 3186 3187 return PackageManager.PERMISSION_DENIED; 3188 } 3189 3190 @Override checkUidPermission(String permName, int uid)3191 public int checkUidPermission(String permName, int uid) { 3192 final int userId = UserHandle.getUserId(uid); 3193 3194 if (!sUserManager.exists(userId)) { 3195 return PackageManager.PERMISSION_DENIED; 3196 } 3197 3198 synchronized (mPackages) { 3199 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3200 if (obj != null) { 3201 final SettingBase ps = (SettingBase) obj; 3202 final PermissionsState permissionsState = ps.getPermissionsState(); 3203 if (permissionsState.hasPermission(permName, userId)) { 3204 return PackageManager.PERMISSION_GRANTED; 3205 } 3206 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3207 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3208 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3209 return PackageManager.PERMISSION_GRANTED; 3210 } 3211 } else { 3212 ArraySet<String> perms = mSystemPermissions.get(uid); 3213 if (perms != null) { 3214 if (perms.contains(permName)) { 3215 return PackageManager.PERMISSION_GRANTED; 3216 } 3217 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3218 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3219 return PackageManager.PERMISSION_GRANTED; 3220 } 3221 } 3222 } 3223 } 3224 3225 return PackageManager.PERMISSION_DENIED; 3226 } 3227 3228 @Override isPermissionRevokedByPolicy(String permission, String packageName, int userId)3229 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3230 if (UserHandle.getCallingUserId() != userId) { 3231 mContext.enforceCallingPermission( 3232 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3233 "isPermissionRevokedByPolicy for user " + userId); 3234 } 3235 3236 if (checkPermission(permission, packageName, userId) 3237 == PackageManager.PERMISSION_GRANTED) { 3238 return false; 3239 } 3240 3241 final long identity = Binder.clearCallingIdentity(); 3242 try { 3243 final int flags = getPermissionFlags(permission, packageName, userId); 3244 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3245 } finally { 3246 Binder.restoreCallingIdentity(identity); 3247 } 3248 } 3249 3250 @Override getPermissionControllerPackageName()3251 public String getPermissionControllerPackageName() { 3252 synchronized (mPackages) { 3253 return mRequiredInstallerPackage; 3254 } 3255 } 3256 3257 /** 3258 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3259 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3260 * @param checkShell TODO(yamasani): 3261 * @param message the message to log on security exception 3262 */ enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message)3263 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3264 boolean checkShell, String message) { 3265 if (userId < 0) { 3266 throw new IllegalArgumentException("Invalid userId " + userId); 3267 } 3268 if (checkShell) { 3269 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3270 } 3271 if (userId == UserHandle.getUserId(callingUid)) return; 3272 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3273 if (requireFullPermission) { 3274 mContext.enforceCallingOrSelfPermission( 3275 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3276 } else { 3277 try { 3278 mContext.enforceCallingOrSelfPermission( 3279 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3280 } catch (SecurityException se) { 3281 mContext.enforceCallingOrSelfPermission( 3282 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3283 } 3284 } 3285 } 3286 } 3287 enforceShellRestriction(String restriction, int callingUid, int userHandle)3288 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3289 if (callingUid == Process.SHELL_UID) { 3290 if (userHandle >= 0 3291 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3292 throw new SecurityException("Shell does not have permission to access user " 3293 + userHandle); 3294 } else if (userHandle < 0) { 3295 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3296 + Debug.getCallers(3)); 3297 } 3298 } 3299 } 3300 findPermissionTreeLP(String permName)3301 private BasePermission findPermissionTreeLP(String permName) { 3302 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3303 if (permName.startsWith(bp.name) && 3304 permName.length() > bp.name.length() && 3305 permName.charAt(bp.name.length()) == '.') { 3306 return bp; 3307 } 3308 } 3309 return null; 3310 } 3311 checkPermissionTreeLP(String permName)3312 private BasePermission checkPermissionTreeLP(String permName) { 3313 if (permName != null) { 3314 BasePermission bp = findPermissionTreeLP(permName); 3315 if (bp != null) { 3316 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3317 return bp; 3318 } 3319 throw new SecurityException("Calling uid " 3320 + Binder.getCallingUid() 3321 + " is not allowed to add to permission tree " 3322 + bp.name + " owned by uid " + bp.uid); 3323 } 3324 } 3325 throw new SecurityException("No permission tree found for " + permName); 3326 } 3327 compareStrings(CharSequence s1, CharSequence s2)3328 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3329 if (s1 == null) { 3330 return s2 == null; 3331 } 3332 if (s2 == null) { 3333 return false; 3334 } 3335 if (s1.getClass() != s2.getClass()) { 3336 return false; 3337 } 3338 return s1.equals(s2); 3339 } 3340 comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2)3341 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3342 if (pi1.icon != pi2.icon) return false; 3343 if (pi1.logo != pi2.logo) return false; 3344 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3345 if (!compareStrings(pi1.name, pi2.name)) return false; 3346 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3347 // We'll take care of setting this one. 3348 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3349 // These are not currently stored in settings. 3350 //if (!compareStrings(pi1.group, pi2.group)) return false; 3351 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3352 //if (pi1.labelRes != pi2.labelRes) return false; 3353 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3354 return true; 3355 } 3356 permissionInfoFootprint(PermissionInfo info)3357 int permissionInfoFootprint(PermissionInfo info) { 3358 int size = info.name.length(); 3359 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3360 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3361 return size; 3362 } 3363 calculateCurrentPermissionFootprintLocked(BasePermission tree)3364 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3365 int size = 0; 3366 for (BasePermission perm : mSettings.mPermissions.values()) { 3367 if (perm.uid == tree.uid) { 3368 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3369 } 3370 } 3371 return size; 3372 } 3373 enforcePermissionCapLocked(PermissionInfo info, BasePermission tree)3374 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3375 // We calculate the max size of permissions defined by this uid and throw 3376 // if that plus the size of 'info' would exceed our stated maximum. 3377 if (tree.uid != Process.SYSTEM_UID) { 3378 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3379 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3380 throw new SecurityException("Permission tree size cap exceeded"); 3381 } 3382 } 3383 } 3384 addPermissionLocked(PermissionInfo info, boolean async)3385 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3386 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3387 throw new SecurityException("Label must be specified in permission"); 3388 } 3389 BasePermission tree = checkPermissionTreeLP(info.name); 3390 BasePermission bp = mSettings.mPermissions.get(info.name); 3391 boolean added = bp == null; 3392 boolean changed = true; 3393 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3394 if (added) { 3395 enforcePermissionCapLocked(info, tree); 3396 bp = new BasePermission(info.name, tree.sourcePackage, 3397 BasePermission.TYPE_DYNAMIC); 3398 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3399 throw new SecurityException( 3400 "Not allowed to modify non-dynamic permission " 3401 + info.name); 3402 } else { 3403 if (bp.protectionLevel == fixedLevel 3404 && bp.perm.owner.equals(tree.perm.owner) 3405 && bp.uid == tree.uid 3406 && comparePermissionInfos(bp.perm.info, info)) { 3407 changed = false; 3408 } 3409 } 3410 bp.protectionLevel = fixedLevel; 3411 info = new PermissionInfo(info); 3412 info.protectionLevel = fixedLevel; 3413 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3414 bp.perm.info.packageName = tree.perm.info.packageName; 3415 bp.uid = tree.uid; 3416 if (added) { 3417 mSettings.mPermissions.put(info.name, bp); 3418 } 3419 if (changed) { 3420 if (!async) { 3421 mSettings.writeLPr(); 3422 } else { 3423 scheduleWriteSettingsLocked(); 3424 } 3425 } 3426 return added; 3427 } 3428 3429 @Override addPermission(PermissionInfo info)3430 public boolean addPermission(PermissionInfo info) { 3431 synchronized (mPackages) { 3432 return addPermissionLocked(info, false); 3433 } 3434 } 3435 3436 @Override addPermissionAsync(PermissionInfo info)3437 public boolean addPermissionAsync(PermissionInfo info) { 3438 synchronized (mPackages) { 3439 return addPermissionLocked(info, true); 3440 } 3441 } 3442 3443 @Override removePermission(String name)3444 public void removePermission(String name) { 3445 synchronized (mPackages) { 3446 checkPermissionTreeLP(name); 3447 BasePermission bp = mSettings.mPermissions.get(name); 3448 if (bp != null) { 3449 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3450 throw new SecurityException( 3451 "Not allowed to modify non-dynamic permission " 3452 + name); 3453 } 3454 mSettings.mPermissions.remove(name); 3455 mSettings.writeLPr(); 3456 } 3457 } 3458 } 3459 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, BasePermission bp)3460 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3461 BasePermission bp) { 3462 int index = pkg.requestedPermissions.indexOf(bp.name); 3463 if (index == -1) { 3464 throw new SecurityException("Package " + pkg.packageName 3465 + " has not requested permission " + bp.name); 3466 } 3467 if (!bp.isRuntime() && !bp.isDevelopment()) { 3468 throw new SecurityException("Permission " + bp.name 3469 + " is not a changeable permission type"); 3470 } 3471 } 3472 3473 @Override grantRuntimePermission(String packageName, String name, final int userId)3474 public void grantRuntimePermission(String packageName, String name, final int userId) { 3475 if (!sUserManager.exists(userId)) { 3476 Log.e(TAG, "No such user:" + userId); 3477 return; 3478 } 3479 3480 mContext.enforceCallingOrSelfPermission( 3481 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3482 "grantRuntimePermission"); 3483 3484 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3485 "grantRuntimePermission"); 3486 3487 final int uid; 3488 final SettingBase sb; 3489 3490 synchronized (mPackages) { 3491 final PackageParser.Package pkg = mPackages.get(packageName); 3492 if (pkg == null) { 3493 throw new IllegalArgumentException("Unknown package: " + packageName); 3494 } 3495 3496 final BasePermission bp = mSettings.mPermissions.get(name); 3497 if (bp == null) { 3498 throw new IllegalArgumentException("Unknown permission: " + name); 3499 } 3500 3501 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3502 3503 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3504 sb = (SettingBase) pkg.mExtras; 3505 if (sb == null) { 3506 throw new IllegalArgumentException("Unknown package: " + packageName); 3507 } 3508 3509 final PermissionsState permissionsState = sb.getPermissionsState(); 3510 3511 final int flags = permissionsState.getPermissionFlags(name, userId); 3512 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3513 throw new SecurityException("Cannot grant system fixed permission: " 3514 + name + " for package: " + packageName); 3515 } 3516 3517 if (bp.isDevelopment()) { 3518 // Development permissions must be handled specially, since they are not 3519 // normal runtime permissions. For now they apply to all users. 3520 if (permissionsState.grantInstallPermission(bp) != 3521 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3522 scheduleWriteSettingsLocked(); 3523 } 3524 return; 3525 } 3526 3527 final int result = permissionsState.grantRuntimePermission(bp, userId); 3528 switch (result) { 3529 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3530 return; 3531 } 3532 3533 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3534 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3535 mHandler.post(new Runnable() { 3536 @Override 3537 public void run() { 3538 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 3539 } 3540 }); 3541 } 3542 break; 3543 } 3544 3545 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3546 3547 // Not critical if that is lost - app has to request again. 3548 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3549 } 3550 3551 // Only need to do this if user is initialized. Otherwise it's a new user 3552 // and there are no processes running as the user yet and there's no need 3553 // to make an expensive call to remount processes for the changed permissions. 3554 if (READ_EXTERNAL_STORAGE.equals(name) 3555 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3556 final long token = Binder.clearCallingIdentity(); 3557 try { 3558 if (sUserManager.isInitialized(userId)) { 3559 MountServiceInternal mountServiceInternal = LocalServices.getService( 3560 MountServiceInternal.class); 3561 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3562 } 3563 } finally { 3564 Binder.restoreCallingIdentity(token); 3565 } 3566 } 3567 } 3568 3569 @Override revokeRuntimePermission(String packageName, String name, int userId)3570 public void revokeRuntimePermission(String packageName, String name, int userId) { 3571 if (!sUserManager.exists(userId)) { 3572 Log.e(TAG, "No such user:" + userId); 3573 return; 3574 } 3575 3576 mContext.enforceCallingOrSelfPermission( 3577 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3578 "revokeRuntimePermission"); 3579 3580 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3581 "revokeRuntimePermission"); 3582 3583 final int appId; 3584 3585 synchronized (mPackages) { 3586 final PackageParser.Package pkg = mPackages.get(packageName); 3587 if (pkg == null) { 3588 throw new IllegalArgumentException("Unknown package: " + packageName); 3589 } 3590 3591 final BasePermission bp = mSettings.mPermissions.get(name); 3592 if (bp == null) { 3593 throw new IllegalArgumentException("Unknown permission: " + name); 3594 } 3595 3596 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3597 3598 SettingBase sb = (SettingBase) pkg.mExtras; 3599 if (sb == null) { 3600 throw new IllegalArgumentException("Unknown package: " + packageName); 3601 } 3602 3603 final PermissionsState permissionsState = sb.getPermissionsState(); 3604 3605 final int flags = permissionsState.getPermissionFlags(name, userId); 3606 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3607 throw new SecurityException("Cannot revoke system fixed permission: " 3608 + name + " for package: " + packageName); 3609 } 3610 3611 if (bp.isDevelopment()) { 3612 // Development permissions must be handled specially, since they are not 3613 // normal runtime permissions. For now they apply to all users. 3614 if (permissionsState.revokeInstallPermission(bp) != 3615 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3616 scheduleWriteSettingsLocked(); 3617 } 3618 return; 3619 } 3620 3621 if (permissionsState.revokeRuntimePermission(bp, userId) == 3622 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3623 return; 3624 } 3625 3626 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 3627 3628 // Critical, after this call app should never have the permission. 3629 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3630 3631 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3632 } 3633 3634 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 3635 } 3636 3637 @Override resetRuntimePermissions()3638 public void resetRuntimePermissions() { 3639 mContext.enforceCallingOrSelfPermission( 3640 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3641 "revokeRuntimePermission"); 3642 3643 int callingUid = Binder.getCallingUid(); 3644 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3645 mContext.enforceCallingOrSelfPermission( 3646 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3647 "resetRuntimePermissions"); 3648 } 3649 3650 synchronized (mPackages) { 3651 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 3652 for (int userId : UserManagerService.getInstance().getUserIds()) { 3653 final int packageCount = mPackages.size(); 3654 for (int i = 0; i < packageCount; i++) { 3655 PackageParser.Package pkg = mPackages.valueAt(i); 3656 if (!(pkg.mExtras instanceof PackageSetting)) { 3657 continue; 3658 } 3659 PackageSetting ps = (PackageSetting) pkg.mExtras; 3660 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 3661 } 3662 } 3663 } 3664 } 3665 3666 @Override getPermissionFlags(String name, String packageName, int userId)3667 public int getPermissionFlags(String name, String packageName, int userId) { 3668 if (!sUserManager.exists(userId)) { 3669 return 0; 3670 } 3671 3672 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 3673 3674 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3675 "getPermissionFlags"); 3676 3677 synchronized (mPackages) { 3678 final PackageParser.Package pkg = mPackages.get(packageName); 3679 if (pkg == null) { 3680 throw new IllegalArgumentException("Unknown package: " + packageName); 3681 } 3682 3683 final BasePermission bp = mSettings.mPermissions.get(name); 3684 if (bp == null) { 3685 throw new IllegalArgumentException("Unknown permission: " + name); 3686 } 3687 3688 SettingBase sb = (SettingBase) pkg.mExtras; 3689 if (sb == null) { 3690 throw new IllegalArgumentException("Unknown package: " + packageName); 3691 } 3692 3693 PermissionsState permissionsState = sb.getPermissionsState(); 3694 return permissionsState.getPermissionFlags(name, userId); 3695 } 3696 } 3697 3698 @Override updatePermissionFlags(String name, String packageName, int flagMask, int flagValues, int userId)3699 public void updatePermissionFlags(String name, String packageName, int flagMask, 3700 int flagValues, int userId) { 3701 if (!sUserManager.exists(userId)) { 3702 return; 3703 } 3704 3705 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 3706 3707 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3708 "updatePermissionFlags"); 3709 3710 // Only the system can change these flags and nothing else. 3711 if (getCallingUid() != Process.SYSTEM_UID) { 3712 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3713 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3714 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 3715 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 3716 } 3717 3718 synchronized (mPackages) { 3719 final PackageParser.Package pkg = mPackages.get(packageName); 3720 if (pkg == null) { 3721 throw new IllegalArgumentException("Unknown package: " + packageName); 3722 } 3723 3724 final BasePermission bp = mSettings.mPermissions.get(name); 3725 if (bp == null) { 3726 throw new IllegalArgumentException("Unknown permission: " + name); 3727 } 3728 3729 SettingBase sb = (SettingBase) pkg.mExtras; 3730 if (sb == null) { 3731 throw new IllegalArgumentException("Unknown package: " + packageName); 3732 } 3733 3734 PermissionsState permissionsState = sb.getPermissionsState(); 3735 3736 // Only the package manager can change flags for system component permissions. 3737 final int flags = permissionsState.getPermissionFlags(bp.name, userId); 3738 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3739 return; 3740 } 3741 3742 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 3743 3744 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 3745 // Install and runtime permissions are stored in different places, 3746 // so figure out what permission changed and persist the change. 3747 if (permissionsState.getInstallPermissionState(name) != null) { 3748 scheduleWriteSettingsLocked(); 3749 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 3750 || hadState) { 3751 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3752 } 3753 } 3754 } 3755 } 3756 3757 /** 3758 * Update the permission flags for all packages and runtime permissions of a user in order 3759 * to allow device or profile owner to remove POLICY_FIXED. 3760 */ 3761 @Override updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId)3762 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 3763 if (!sUserManager.exists(userId)) { 3764 return; 3765 } 3766 3767 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 3768 3769 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3770 "updatePermissionFlagsForAllApps"); 3771 3772 // Only the system can change system fixed flags. 3773 if (getCallingUid() != Process.SYSTEM_UID) { 3774 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3775 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3776 } 3777 3778 synchronized (mPackages) { 3779 boolean changed = false; 3780 final int packageCount = mPackages.size(); 3781 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 3782 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 3783 SettingBase sb = (SettingBase) pkg.mExtras; 3784 if (sb == null) { 3785 continue; 3786 } 3787 PermissionsState permissionsState = sb.getPermissionsState(); 3788 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 3789 userId, flagMask, flagValues); 3790 } 3791 if (changed) { 3792 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3793 } 3794 } 3795 } 3796 enforceGrantRevokeRuntimePermissionPermissions(String message)3797 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 3798 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 3799 != PackageManager.PERMISSION_GRANTED 3800 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 3801 != PackageManager.PERMISSION_GRANTED) { 3802 throw new SecurityException(message + " requires " 3803 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 3804 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 3805 } 3806 } 3807 3808 @Override shouldShowRequestPermissionRationale(String permissionName, String packageName, int userId)3809 public boolean shouldShowRequestPermissionRationale(String permissionName, 3810 String packageName, int userId) { 3811 if (UserHandle.getCallingUserId() != userId) { 3812 mContext.enforceCallingPermission( 3813 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3814 "canShowRequestPermissionRationale for user " + userId); 3815 } 3816 3817 final int uid = getPackageUid(packageName, userId); 3818 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 3819 return false; 3820 } 3821 3822 if (checkPermission(permissionName, packageName, userId) 3823 == PackageManager.PERMISSION_GRANTED) { 3824 return false; 3825 } 3826 3827 final int flags; 3828 3829 final long identity = Binder.clearCallingIdentity(); 3830 try { 3831 flags = getPermissionFlags(permissionName, 3832 packageName, userId); 3833 } finally { 3834 Binder.restoreCallingIdentity(identity); 3835 } 3836 3837 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 3838 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 3839 | PackageManager.FLAG_PERMISSION_USER_FIXED; 3840 3841 if ((flags & fixedFlags) != 0) { 3842 return false; 3843 } 3844 3845 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 3846 } 3847 3848 @Override addOnPermissionsChangeListener(IOnPermissionsChangeListener listener)3849 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3850 mContext.enforceCallingOrSelfPermission( 3851 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 3852 "addOnPermissionsChangeListener"); 3853 3854 synchronized (mPackages) { 3855 mOnPermissionChangeListeners.addListenerLocked(listener); 3856 } 3857 } 3858 3859 @Override removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener)3860 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3861 synchronized (mPackages) { 3862 mOnPermissionChangeListeners.removeListenerLocked(listener); 3863 } 3864 } 3865 3866 @Override isProtectedBroadcast(String actionName)3867 public boolean isProtectedBroadcast(String actionName) { 3868 synchronized (mPackages) { 3869 return mProtectedBroadcasts.contains(actionName); 3870 } 3871 } 3872 3873 @Override checkSignatures(String pkg1, String pkg2)3874 public int checkSignatures(String pkg1, String pkg2) { 3875 synchronized (mPackages) { 3876 final PackageParser.Package p1 = mPackages.get(pkg1); 3877 final PackageParser.Package p2 = mPackages.get(pkg2); 3878 if (p1 == null || p1.mExtras == null 3879 || p2 == null || p2.mExtras == null) { 3880 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3881 } 3882 return compareSignatures(p1.mSignatures, p2.mSignatures); 3883 } 3884 } 3885 3886 @Override checkUidSignatures(int uid1, int uid2)3887 public int checkUidSignatures(int uid1, int uid2) { 3888 // Map to base uids. 3889 uid1 = UserHandle.getAppId(uid1); 3890 uid2 = UserHandle.getAppId(uid2); 3891 // reader 3892 synchronized (mPackages) { 3893 Signature[] s1; 3894 Signature[] s2; 3895 Object obj = mSettings.getUserIdLPr(uid1); 3896 if (obj != null) { 3897 if (obj instanceof SharedUserSetting) { 3898 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 3899 } else if (obj instanceof PackageSetting) { 3900 s1 = ((PackageSetting)obj).signatures.mSignatures; 3901 } else { 3902 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3903 } 3904 } else { 3905 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3906 } 3907 obj = mSettings.getUserIdLPr(uid2); 3908 if (obj != null) { 3909 if (obj instanceof SharedUserSetting) { 3910 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 3911 } else if (obj instanceof PackageSetting) { 3912 s2 = ((PackageSetting)obj).signatures.mSignatures; 3913 } else { 3914 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3915 } 3916 } else { 3917 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3918 } 3919 return compareSignatures(s1, s2); 3920 } 3921 } 3922 killUid(int appId, int userId, String reason)3923 private void killUid(int appId, int userId, String reason) { 3924 final long identity = Binder.clearCallingIdentity(); 3925 try { 3926 IActivityManager am = ActivityManagerNative.getDefault(); 3927 if (am != null) { 3928 try { 3929 am.killUid(appId, userId, reason); 3930 } catch (RemoteException e) { 3931 /* ignore - same process */ 3932 } 3933 } 3934 } finally { 3935 Binder.restoreCallingIdentity(identity); 3936 } 3937 } 3938 3939 /** 3940 * Compares two sets of signatures. Returns: 3941 * <br /> 3942 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 3943 * <br /> 3944 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 3945 * <br /> 3946 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 3947 * <br /> 3948 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 3949 * <br /> 3950 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 3951 */ compareSignatures(Signature[] s1, Signature[] s2)3952 static int compareSignatures(Signature[] s1, Signature[] s2) { 3953 if (s1 == null) { 3954 return s2 == null 3955 ? PackageManager.SIGNATURE_NEITHER_SIGNED 3956 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 3957 } 3958 3959 if (s2 == null) { 3960 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 3961 } 3962 3963 if (s1.length != s2.length) { 3964 return PackageManager.SIGNATURE_NO_MATCH; 3965 } 3966 3967 // Since both signature sets are of size 1, we can compare without HashSets. 3968 if (s1.length == 1) { 3969 return s1[0].equals(s2[0]) ? 3970 PackageManager.SIGNATURE_MATCH : 3971 PackageManager.SIGNATURE_NO_MATCH; 3972 } 3973 3974 ArraySet<Signature> set1 = new ArraySet<Signature>(); 3975 for (Signature sig : s1) { 3976 set1.add(sig); 3977 } 3978 ArraySet<Signature> set2 = new ArraySet<Signature>(); 3979 for (Signature sig : s2) { 3980 set2.add(sig); 3981 } 3982 // Make sure s2 contains all signatures in s1. 3983 if (set1.equals(set2)) { 3984 return PackageManager.SIGNATURE_MATCH; 3985 } 3986 return PackageManager.SIGNATURE_NO_MATCH; 3987 } 3988 3989 /** 3990 * If the database version for this type of package (internal storage or 3991 * external storage) is less than the version where package signatures 3992 * were updated, return true. 3993 */ isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg)3994 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3995 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 3996 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 3997 } 3998 3999 /** 4000 * Used for backward compatibility to make sure any packages with 4001 * certificate chains get upgraded to the new style. {@code existingSigs} 4002 * will be in the old format (since they were stored on disk from before the 4003 * system upgrade) and {@code scannedSigs} will be in the newer format. 4004 */ compareSignaturesCompat(PackageSignatures existingSigs, PackageParser.Package scannedPkg)4005 private int compareSignaturesCompat(PackageSignatures existingSigs, 4006 PackageParser.Package scannedPkg) { 4007 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4008 return PackageManager.SIGNATURE_NO_MATCH; 4009 } 4010 4011 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4012 for (Signature sig : existingSigs.mSignatures) { 4013 existingSet.add(sig); 4014 } 4015 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4016 for (Signature sig : scannedPkg.mSignatures) { 4017 try { 4018 Signature[] chainSignatures = sig.getChainSignatures(); 4019 for (Signature chainSig : chainSignatures) { 4020 scannedCompatSet.add(chainSig); 4021 } 4022 } catch (CertificateEncodingException e) { 4023 scannedCompatSet.add(sig); 4024 } 4025 } 4026 /* 4027 * Make sure the expanded scanned set contains all signatures in the 4028 * existing one. 4029 */ 4030 if (scannedCompatSet.equals(existingSet)) { 4031 // Migrate the old signatures to the new scheme. 4032 existingSigs.assignSignatures(scannedPkg.mSignatures); 4033 // The new KeySets will be re-added later in the scanning process. 4034 synchronized (mPackages) { 4035 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4036 } 4037 return PackageManager.SIGNATURE_MATCH; 4038 } 4039 return PackageManager.SIGNATURE_NO_MATCH; 4040 } 4041 isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg)4042 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4043 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4044 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4045 } 4046 compareSignaturesRecover(PackageSignatures existingSigs, PackageParser.Package scannedPkg)4047 private int compareSignaturesRecover(PackageSignatures existingSigs, 4048 PackageParser.Package scannedPkg) { 4049 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4050 return PackageManager.SIGNATURE_NO_MATCH; 4051 } 4052 4053 String msg = null; 4054 try { 4055 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4056 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4057 + scannedPkg.packageName); 4058 return PackageManager.SIGNATURE_MATCH; 4059 } 4060 } catch (CertificateException e) { 4061 msg = e.getMessage(); 4062 } 4063 4064 logCriticalInfo(Log.INFO, 4065 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4066 return PackageManager.SIGNATURE_NO_MATCH; 4067 } 4068 4069 @Override getPackagesForUid(int uid)4070 public String[] getPackagesForUid(int uid) { 4071 uid = UserHandle.getAppId(uid); 4072 // reader 4073 synchronized (mPackages) { 4074 Object obj = mSettings.getUserIdLPr(uid); 4075 if (obj instanceof SharedUserSetting) { 4076 final SharedUserSetting sus = (SharedUserSetting) obj; 4077 final int N = sus.packages.size(); 4078 final String[] res = new String[N]; 4079 final Iterator<PackageSetting> it = sus.packages.iterator(); 4080 int i = 0; 4081 while (it.hasNext()) { 4082 res[i++] = it.next().name; 4083 } 4084 return res; 4085 } else if (obj instanceof PackageSetting) { 4086 final PackageSetting ps = (PackageSetting) obj; 4087 return new String[] { ps.name }; 4088 } 4089 } 4090 return null; 4091 } 4092 4093 @Override getNameForUid(int uid)4094 public String getNameForUid(int uid) { 4095 // reader 4096 synchronized (mPackages) { 4097 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4098 if (obj instanceof SharedUserSetting) { 4099 final SharedUserSetting sus = (SharedUserSetting) obj; 4100 return sus.name + ":" + sus.userId; 4101 } else if (obj instanceof PackageSetting) { 4102 final PackageSetting ps = (PackageSetting) obj; 4103 return ps.name; 4104 } 4105 } 4106 return null; 4107 } 4108 4109 @Override getUidForSharedUser(String sharedUserName)4110 public int getUidForSharedUser(String sharedUserName) { 4111 if(sharedUserName == null) { 4112 return -1; 4113 } 4114 // reader 4115 synchronized (mPackages) { 4116 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4117 if (suid == null) { 4118 return -1; 4119 } 4120 return suid.userId; 4121 } 4122 } 4123 4124 @Override getFlagsForUid(int uid)4125 public int getFlagsForUid(int uid) { 4126 synchronized (mPackages) { 4127 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4128 if (obj instanceof SharedUserSetting) { 4129 final SharedUserSetting sus = (SharedUserSetting) obj; 4130 return sus.pkgFlags; 4131 } else if (obj instanceof PackageSetting) { 4132 final PackageSetting ps = (PackageSetting) obj; 4133 return ps.pkgFlags; 4134 } 4135 } 4136 return 0; 4137 } 4138 4139 @Override getPrivateFlagsForUid(int uid)4140 public int getPrivateFlagsForUid(int uid) { 4141 synchronized (mPackages) { 4142 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4143 if (obj instanceof SharedUserSetting) { 4144 final SharedUserSetting sus = (SharedUserSetting) obj; 4145 return sus.pkgPrivateFlags; 4146 } else if (obj instanceof PackageSetting) { 4147 final PackageSetting ps = (PackageSetting) obj; 4148 return ps.pkgPrivateFlags; 4149 } 4150 } 4151 return 0; 4152 } 4153 4154 @Override isUidPrivileged(int uid)4155 public boolean isUidPrivileged(int uid) { 4156 uid = UserHandle.getAppId(uid); 4157 // reader 4158 synchronized (mPackages) { 4159 Object obj = mSettings.getUserIdLPr(uid); 4160 if (obj instanceof SharedUserSetting) { 4161 final SharedUserSetting sus = (SharedUserSetting) obj; 4162 final Iterator<PackageSetting> it = sus.packages.iterator(); 4163 while (it.hasNext()) { 4164 if (it.next().isPrivileged()) { 4165 return true; 4166 } 4167 } 4168 } else if (obj instanceof PackageSetting) { 4169 final PackageSetting ps = (PackageSetting) obj; 4170 return ps.isPrivileged(); 4171 } 4172 } 4173 return false; 4174 } 4175 4176 @Override getAppOpPermissionPackages(String permissionName)4177 public String[] getAppOpPermissionPackages(String permissionName) { 4178 synchronized (mPackages) { 4179 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4180 if (pkgs == null) { 4181 return null; 4182 } 4183 return pkgs.toArray(new String[pkgs.size()]); 4184 } 4185 } 4186 4187 @Override resolveIntent(Intent intent, String resolvedType, int flags, int userId)4188 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4189 int flags, int userId) { 4190 if (!sUserManager.exists(userId)) return null; 4191 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 4192 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4193 return chooseBestActivity(intent, resolvedType, flags, query, userId); 4194 } 4195 4196 @Override setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)4197 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4198 IntentFilter filter, int match, ComponentName activity) { 4199 final int userId = UserHandle.getCallingUserId(); 4200 if (DEBUG_PREFERRED) { 4201 Log.v(TAG, "setLastChosenActivity intent=" + intent 4202 + " resolvedType=" + resolvedType 4203 + " flags=" + flags 4204 + " filter=" + filter 4205 + " match=" + match 4206 + " activity=" + activity); 4207 filter.dump(new PrintStreamPrinter(System.out), " "); 4208 } 4209 intent.setComponent(null); 4210 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4211 // Find any earlier preferred or last chosen entries and nuke them 4212 findPreferredActivity(intent, resolvedType, 4213 flags, query, 0, false, true, false, userId); 4214 // Add the new activity as the last chosen for this filter 4215 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4216 "Setting last chosen"); 4217 } 4218 4219 @Override getLastChosenActivity(Intent intent, String resolvedType, int flags)4220 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4221 final int userId = UserHandle.getCallingUserId(); 4222 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4223 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4224 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4225 false, false, false, userId); 4226 } 4227 chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int userId)4228 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4229 int flags, List<ResolveInfo> query, int userId) { 4230 if (query != null) { 4231 final int N = query.size(); 4232 if (N == 1) { 4233 return query.get(0); 4234 } else if (N > 1) { 4235 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4236 // If there is more than one activity with the same priority, 4237 // then let the user decide between them. 4238 ResolveInfo r0 = query.get(0); 4239 ResolveInfo r1 = query.get(1); 4240 if (DEBUG_INTENT_MATCHING || debug) { 4241 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4242 + r1.activityInfo.name + "=" + r1.priority); 4243 } 4244 // If the first activity has a higher priority, or a different 4245 // default, then it is always desireable to pick it. 4246 if (r0.priority != r1.priority 4247 || r0.preferredOrder != r1.preferredOrder 4248 || r0.isDefault != r1.isDefault) { 4249 return query.get(0); 4250 } 4251 // If we have saved a preference for a preferred activity for 4252 // this Intent, use that. 4253 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4254 flags, query, r0.priority, true, false, debug, userId); 4255 if (ri != null) { 4256 return ri; 4257 } 4258 ri = new ResolveInfo(mResolveInfo); 4259 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4260 ri.activityInfo.applicationInfo = new ApplicationInfo( 4261 ri.activityInfo.applicationInfo); 4262 if (userId != 0) { 4263 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4264 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4265 } 4266 // Make sure that the resolver is displayable in car mode 4267 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4268 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4269 return ri; 4270 } 4271 } 4272 return null; 4273 } 4274 findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)4275 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4276 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4277 final int N = query.size(); 4278 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4279 .get(userId); 4280 // Get the list of persistent preferred activities that handle the intent 4281 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4282 List<PersistentPreferredActivity> pprefs = ppir != null 4283 ? ppir.queryIntent(intent, resolvedType, 4284 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4285 : null; 4286 if (pprefs != null && pprefs.size() > 0) { 4287 final int M = pprefs.size(); 4288 for (int i=0; i<M; i++) { 4289 final PersistentPreferredActivity ppa = pprefs.get(i); 4290 if (DEBUG_PREFERRED || debug) { 4291 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4292 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4293 + "\n component=" + ppa.mComponent); 4294 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4295 } 4296 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4297 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 4298 if (DEBUG_PREFERRED || debug) { 4299 Slog.v(TAG, "Found persistent preferred activity:"); 4300 if (ai != null) { 4301 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4302 } else { 4303 Slog.v(TAG, " null"); 4304 } 4305 } 4306 if (ai == null) { 4307 // This previously registered persistent preferred activity 4308 // component is no longer known. Ignore it and do NOT remove it. 4309 continue; 4310 } 4311 for (int j=0; j<N; j++) { 4312 final ResolveInfo ri = query.get(j); 4313 if (!ri.activityInfo.applicationInfo.packageName 4314 .equals(ai.applicationInfo.packageName)) { 4315 continue; 4316 } 4317 if (!ri.activityInfo.name.equals(ai.name)) { 4318 continue; 4319 } 4320 // Found a persistent preference that can handle the intent. 4321 if (DEBUG_PREFERRED || debug) { 4322 Slog.v(TAG, "Returning persistent preferred activity: " + 4323 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4324 } 4325 return ri; 4326 } 4327 } 4328 } 4329 return null; 4330 } 4331 findPreferredActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)4332 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4333 List<ResolveInfo> query, int priority, boolean always, 4334 boolean removeMatches, boolean debug, int userId) { 4335 if (!sUserManager.exists(userId)) return null; 4336 // writer 4337 synchronized (mPackages) { 4338 if (intent.getSelector() != null) { 4339 intent = intent.getSelector(); 4340 } 4341 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4342 4343 // Try to find a matching persistent preferred activity. 4344 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4345 debug, userId); 4346 4347 // If a persistent preferred activity matched, use it. 4348 if (pri != null) { 4349 return pri; 4350 } 4351 4352 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4353 // Get the list of preferred activities that handle the intent 4354 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4355 List<PreferredActivity> prefs = pir != null 4356 ? pir.queryIntent(intent, resolvedType, 4357 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4358 : null; 4359 if (prefs != null && prefs.size() > 0) { 4360 boolean changed = false; 4361 try { 4362 // First figure out how good the original match set is. 4363 // We will only allow preferred activities that came 4364 // from the same match quality. 4365 int match = 0; 4366 4367 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4368 4369 final int N = query.size(); 4370 for (int j=0; j<N; j++) { 4371 final ResolveInfo ri = query.get(j); 4372 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4373 + ": 0x" + Integer.toHexString(match)); 4374 if (ri.match > match) { 4375 match = ri.match; 4376 } 4377 } 4378 4379 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4380 + Integer.toHexString(match)); 4381 4382 match &= IntentFilter.MATCH_CATEGORY_MASK; 4383 final int M = prefs.size(); 4384 for (int i=0; i<M; i++) { 4385 final PreferredActivity pa = prefs.get(i); 4386 if (DEBUG_PREFERRED || debug) { 4387 Slog.v(TAG, "Checking PreferredActivity ds=" 4388 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4389 + "\n component=" + pa.mPref.mComponent); 4390 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4391 } 4392 if (pa.mPref.mMatch != match) { 4393 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4394 + Integer.toHexString(pa.mPref.mMatch)); 4395 continue; 4396 } 4397 // If it's not an "always" type preferred activity and that's what we're 4398 // looking for, skip it. 4399 if (always && !pa.mPref.mAlways) { 4400 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4401 continue; 4402 } 4403 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4404 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 4405 if (DEBUG_PREFERRED || debug) { 4406 Slog.v(TAG, "Found preferred activity:"); 4407 if (ai != null) { 4408 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4409 } else { 4410 Slog.v(TAG, " null"); 4411 } 4412 } 4413 if (ai == null) { 4414 // This previously registered preferred activity 4415 // component is no longer known. Most likely an update 4416 // to the app was installed and in the new version this 4417 // component no longer exists. Clean it up by removing 4418 // it from the preferred activities list, and skip it. 4419 Slog.w(TAG, "Removing dangling preferred activity: " 4420 + pa.mPref.mComponent); 4421 pir.removeFilter(pa); 4422 changed = true; 4423 continue; 4424 } 4425 for (int j=0; j<N; j++) { 4426 final ResolveInfo ri = query.get(j); 4427 if (!ri.activityInfo.applicationInfo.packageName 4428 .equals(ai.applicationInfo.packageName)) { 4429 continue; 4430 } 4431 if (!ri.activityInfo.name.equals(ai.name)) { 4432 continue; 4433 } 4434 4435 if (removeMatches) { 4436 pir.removeFilter(pa); 4437 changed = true; 4438 if (DEBUG_PREFERRED) { 4439 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4440 } 4441 break; 4442 } 4443 4444 // Okay we found a previously set preferred or last chosen app. 4445 // If the result set is different from when this 4446 // was created, we need to clear it and re-ask the 4447 // user their preference, if we're looking for an "always" type entry. 4448 if (always && !pa.mPref.sameSet(query)) { 4449 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4450 + intent + " type " + resolvedType); 4451 if (DEBUG_PREFERRED) { 4452 Slog.v(TAG, "Removing preferred activity since set changed " 4453 + pa.mPref.mComponent); 4454 } 4455 pir.removeFilter(pa); 4456 // Re-add the filter as a "last chosen" entry (!always) 4457 PreferredActivity lastChosen = new PreferredActivity( 4458 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4459 pir.addFilter(lastChosen); 4460 changed = true; 4461 return null; 4462 } 4463 4464 // Yay! Either the set matched or we're looking for the last chosen 4465 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4466 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4467 return ri; 4468 } 4469 } 4470 } finally { 4471 if (changed) { 4472 if (DEBUG_PREFERRED) { 4473 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 4474 } 4475 scheduleWritePackageRestrictionsLocked(userId); 4476 } 4477 } 4478 } 4479 } 4480 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 4481 return null; 4482 } 4483 4484 /* 4485 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 4486 */ 4487 @Override canForwardTo(Intent intent, String resolvedType, int sourceUserId, int targetUserId)4488 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 4489 int targetUserId) { 4490 mContext.enforceCallingOrSelfPermission( 4491 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 4492 List<CrossProfileIntentFilter> matches = 4493 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 4494 if (matches != null) { 4495 int size = matches.size(); 4496 for (int i = 0; i < size; i++) { 4497 if (matches.get(i).getTargetUserId() == targetUserId) return true; 4498 } 4499 } 4500 if (hasWebURI(intent)) { 4501 // cross-profile app linking works only towards the parent. 4502 final UserInfo parent = getProfileParent(sourceUserId); 4503 synchronized(mPackages) { 4504 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 4505 intent, resolvedType, 0, sourceUserId, parent.id); 4506 return xpDomainInfo != null; 4507 } 4508 } 4509 return false; 4510 } 4511 getProfileParent(int userId)4512 private UserInfo getProfileParent(int userId) { 4513 final long identity = Binder.clearCallingIdentity(); 4514 try { 4515 return sUserManager.getProfileParent(userId); 4516 } finally { 4517 Binder.restoreCallingIdentity(identity); 4518 } 4519 } 4520 getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)4521 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 4522 String resolvedType, int userId) { 4523 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 4524 if (resolver != null) { 4525 return resolver.queryIntent(intent, resolvedType, false, userId); 4526 } 4527 return null; 4528 } 4529 4530 @Override queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)4531 public List<ResolveInfo> queryIntentActivities(Intent intent, 4532 String resolvedType, int flags, int userId) { 4533 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4534 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 4535 ComponentName comp = intent.getComponent(); 4536 if (comp == null) { 4537 if (intent.getSelector() != null) { 4538 intent = intent.getSelector(); 4539 comp = intent.getComponent(); 4540 } 4541 } 4542 4543 if (comp != null) { 4544 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4545 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 4546 if (ai != null) { 4547 final ResolveInfo ri = new ResolveInfo(); 4548 ri.activityInfo = ai; 4549 list.add(ri); 4550 } 4551 return list; 4552 } 4553 4554 // reader 4555 synchronized (mPackages) { 4556 final String pkgName = intent.getPackage(); 4557 if (pkgName == null) { 4558 List<CrossProfileIntentFilter> matchingFilters = 4559 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 4560 // Check for results that need to skip the current profile. 4561 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 4562 resolvedType, flags, userId); 4563 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 4564 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 4565 result.add(xpResolveInfo); 4566 return filterIfNotPrimaryUser(result, userId); 4567 } 4568 4569 // Check for results in the current profile. 4570 List<ResolveInfo> result = mActivities.queryIntent( 4571 intent, resolvedType, flags, userId); 4572 4573 // Check for cross profile results. 4574 xpResolveInfo = queryCrossProfileIntents( 4575 matchingFilters, intent, resolvedType, flags, userId); 4576 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 4577 result.add(xpResolveInfo); 4578 Collections.sort(result, mResolvePrioritySorter); 4579 } 4580 result = filterIfNotPrimaryUser(result, userId); 4581 if (hasWebURI(intent)) { 4582 CrossProfileDomainInfo xpDomainInfo = null; 4583 final UserInfo parent = getProfileParent(userId); 4584 if (parent != null) { 4585 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 4586 flags, userId, parent.id); 4587 } 4588 if (xpDomainInfo != null) { 4589 if (xpResolveInfo != null) { 4590 // If we didn't remove it, the cross-profile ResolveInfo would be twice 4591 // in the result. 4592 result.remove(xpResolveInfo); 4593 } 4594 if (result.size() == 0) { 4595 result.add(xpDomainInfo.resolveInfo); 4596 return result; 4597 } 4598 } else if (result.size() <= 1) { 4599 return result; 4600 } 4601 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 4602 xpDomainInfo, userId); 4603 Collections.sort(result, mResolvePrioritySorter); 4604 } 4605 return result; 4606 } 4607 final PackageParser.Package pkg = mPackages.get(pkgName); 4608 if (pkg != null) { 4609 return filterIfNotPrimaryUser( 4610 mActivities.queryIntentForPackage( 4611 intent, resolvedType, flags, pkg.activities, userId), 4612 userId); 4613 } 4614 return new ArrayList<ResolveInfo>(); 4615 } 4616 } 4617 4618 private static class CrossProfileDomainInfo { 4619 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 4620 ResolveInfo resolveInfo; 4621 /* Best domain verification status of the activities found in the other profile */ 4622 int bestDomainVerificationStatus; 4623 } 4624 getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)4625 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 4626 String resolvedType, int flags, int sourceUserId, int parentUserId) { 4627 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 4628 sourceUserId)) { 4629 return null; 4630 } 4631 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4632 resolvedType, flags, parentUserId); 4633 4634 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 4635 return null; 4636 } 4637 CrossProfileDomainInfo result = null; 4638 int size = resultTargetUser.size(); 4639 for (int i = 0; i < size; i++) { 4640 ResolveInfo riTargetUser = resultTargetUser.get(i); 4641 // Intent filter verification is only for filters that specify a host. So don't return 4642 // those that handle all web uris. 4643 if (riTargetUser.handleAllWebDataURI) { 4644 continue; 4645 } 4646 String packageName = riTargetUser.activityInfo.packageName; 4647 PackageSetting ps = mSettings.mPackages.get(packageName); 4648 if (ps == null) { 4649 continue; 4650 } 4651 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 4652 int status = (int)(verificationState >> 32); 4653 if (result == null) { 4654 result = new CrossProfileDomainInfo(); 4655 result.resolveInfo = 4656 createForwardingResolveInfo(new IntentFilter(), sourceUserId, parentUserId); 4657 result.bestDomainVerificationStatus = status; 4658 } else { 4659 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 4660 result.bestDomainVerificationStatus); 4661 } 4662 } 4663 // Don't consider matches with status NEVER across profiles. 4664 if (result != null && result.bestDomainVerificationStatus 4665 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4666 return null; 4667 } 4668 return result; 4669 } 4670 4671 /** 4672 * Verification statuses are ordered from the worse to the best, except for 4673 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 4674 */ bestDomainVerificationStatus(int status1, int status2)4675 private int bestDomainVerificationStatus(int status1, int status2) { 4676 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4677 return status2; 4678 } 4679 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4680 return status1; 4681 } 4682 return (int) MathUtils.max(status1, status2); 4683 } 4684 isUserEnabled(int userId)4685 private boolean isUserEnabled(int userId) { 4686 long callingId = Binder.clearCallingIdentity(); 4687 try { 4688 UserInfo userInfo = sUserManager.getUserInfo(userId); 4689 return userInfo != null && userInfo.isEnabled(); 4690 } finally { 4691 Binder.restoreCallingIdentity(callingId); 4692 } 4693 } 4694 4695 /** 4696 * Filter out activities with primaryUserOnly flag set, when current user is not the owner. 4697 * 4698 * @return filtered list 4699 */ filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId)4700 private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) { 4701 if (userId == UserHandle.USER_OWNER) { 4702 return resolveInfos; 4703 } 4704 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 4705 ResolveInfo info = resolveInfos.get(i); 4706 if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 4707 resolveInfos.remove(i); 4708 } 4709 } 4710 return resolveInfos; 4711 } 4712 hasWebURI(Intent intent)4713 private static boolean hasWebURI(Intent intent) { 4714 if (intent.getData() == null) { 4715 return false; 4716 } 4717 final String scheme = intent.getScheme(); 4718 if (TextUtils.isEmpty(scheme)) { 4719 return false; 4720 } 4721 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 4722 } 4723 filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId)4724 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 4725 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 4726 int userId) { 4727 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 4728 4729 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 4730 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 4731 candidates.size()); 4732 } 4733 4734 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 4735 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 4736 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 4737 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 4738 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 4739 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 4740 4741 synchronized (mPackages) { 4742 final int count = candidates.size(); 4743 // First, try to use linked apps. Partition the candidates into four lists: 4744 // one for the final results, one for the "do not use ever", one for "undefined status" 4745 // and finally one for "browser app type". 4746 for (int n=0; n<count; n++) { 4747 ResolveInfo info = candidates.get(n); 4748 String packageName = info.activityInfo.packageName; 4749 PackageSetting ps = mSettings.mPackages.get(packageName); 4750 if (ps != null) { 4751 // Add to the special match all list (Browser use case) 4752 if (info.handleAllWebDataURI) { 4753 matchAllList.add(info); 4754 continue; 4755 } 4756 // Try to get the status from User settings first 4757 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4758 int status = (int)(packedStatus >> 32); 4759 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 4760 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 4761 if (DEBUG_DOMAIN_VERIFICATION) { 4762 Slog.i(TAG, " + always: " + info.activityInfo.packageName 4763 + " : linkgen=" + linkGeneration); 4764 } 4765 // Use link-enabled generation as preferredOrder, i.e. 4766 // prefer newly-enabled over earlier-enabled. 4767 info.preferredOrder = linkGeneration; 4768 alwaysList.add(info); 4769 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4770 if (DEBUG_DOMAIN_VERIFICATION) { 4771 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 4772 } 4773 neverList.add(info); 4774 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4775 if (DEBUG_DOMAIN_VERIFICATION) { 4776 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 4777 } 4778 alwaysAskList.add(info); 4779 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 4780 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 4781 if (DEBUG_DOMAIN_VERIFICATION) { 4782 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 4783 } 4784 undefinedList.add(info); 4785 } 4786 } 4787 } 4788 4789 // We'll want to include browser possibilities in a few cases 4790 boolean includeBrowser = false; 4791 4792 // First try to add the "always" resolution(s) for the current user, if any 4793 if (alwaysList.size() > 0) { 4794 result.addAll(alwaysList); 4795 } else { 4796 // Add all undefined apps as we want them to appear in the disambiguation dialog. 4797 result.addAll(undefinedList); 4798 // Maybe add one for the other profile. 4799 if (xpDomainInfo != null && ( 4800 xpDomainInfo.bestDomainVerificationStatus 4801 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 4802 result.add(xpDomainInfo.resolveInfo); 4803 } 4804 includeBrowser = true; 4805 } 4806 4807 // The presence of any 'always ask' alternatives means we'll also offer browsers. 4808 // If there were 'always' entries their preferred order has been set, so we also 4809 // back that off to make the alternatives equivalent 4810 if (alwaysAskList.size() > 0) { 4811 for (ResolveInfo i : result) { 4812 i.preferredOrder = 0; 4813 } 4814 result.addAll(alwaysAskList); 4815 includeBrowser = true; 4816 } 4817 4818 if (includeBrowser) { 4819 // Also add browsers (all of them or only the default one) 4820 if (DEBUG_DOMAIN_VERIFICATION) { 4821 Slog.v(TAG, " ...including browsers in candidate set"); 4822 } 4823 if ((matchFlags & MATCH_ALL) != 0) { 4824 result.addAll(matchAllList); 4825 } else { 4826 // Browser/generic handling case. If there's a default browser, go straight 4827 // to that (but only if there is no other higher-priority match). 4828 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 4829 int maxMatchPrio = 0; 4830 ResolveInfo defaultBrowserMatch = null; 4831 final int numCandidates = matchAllList.size(); 4832 for (int n = 0; n < numCandidates; n++) { 4833 ResolveInfo info = matchAllList.get(n); 4834 // track the highest overall match priority... 4835 if (info.priority > maxMatchPrio) { 4836 maxMatchPrio = info.priority; 4837 } 4838 // ...and the highest-priority default browser match 4839 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 4840 if (defaultBrowserMatch == null 4841 || (defaultBrowserMatch.priority < info.priority)) { 4842 if (debug) { 4843 Slog.v(TAG, "Considering default browser match " + info); 4844 } 4845 defaultBrowserMatch = info; 4846 } 4847 } 4848 } 4849 if (defaultBrowserMatch != null 4850 && defaultBrowserMatch.priority >= maxMatchPrio 4851 && !TextUtils.isEmpty(defaultBrowserPackageName)) 4852 { 4853 if (debug) { 4854 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 4855 } 4856 result.add(defaultBrowserMatch); 4857 } else { 4858 result.addAll(matchAllList); 4859 } 4860 } 4861 4862 // If there is nothing selected, add all candidates and remove the ones that the user 4863 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 4864 if (result.size() == 0) { 4865 result.addAll(candidates); 4866 result.removeAll(neverList); 4867 } 4868 } 4869 } 4870 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 4871 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 4872 result.size()); 4873 for (ResolveInfo info : result) { 4874 Slog.v(TAG, " + " + info.activityInfo); 4875 } 4876 } 4877 return result; 4878 } 4879 4880 // Returns a packed value as a long: 4881 // 4882 // high 'int'-sized word: link status: undefined/ask/never/always. 4883 // low 'int'-sized word: relative priority among 'always' results. getDomainVerificationStatusLPr(PackageSetting ps, int userId)4884 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 4885 long result = ps.getDomainVerificationStatusForUser(userId); 4886 // if none available, get the master status 4887 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4888 if (ps.getIntentFilterVerificationInfo() != null) { 4889 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 4890 } 4891 } 4892 return result; 4893 } 4894 querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)4895 private ResolveInfo querySkipCurrentProfileIntents( 4896 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4897 int flags, int sourceUserId) { 4898 if (matchingFilters != null) { 4899 int size = matchingFilters.size(); 4900 for (int i = 0; i < size; i ++) { 4901 CrossProfileIntentFilter filter = matchingFilters.get(i); 4902 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 4903 // Checking if there are activities in the target user that can handle the 4904 // intent. 4905 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4906 flags, sourceUserId); 4907 if (resolveInfo != null) { 4908 return resolveInfo; 4909 } 4910 } 4911 } 4912 } 4913 return null; 4914 } 4915 4916 // Return matching ResolveInfo if any for skip current profile intent filters. queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)4917 private ResolveInfo queryCrossProfileIntents( 4918 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4919 int flags, int sourceUserId) { 4920 if (matchingFilters != null) { 4921 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 4922 // match the same intent. For performance reasons, it is better not to 4923 // run queryIntent twice for the same userId 4924 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 4925 int size = matchingFilters.size(); 4926 for (int i = 0; i < size; i++) { 4927 CrossProfileIntentFilter filter = matchingFilters.get(i); 4928 int targetUserId = filter.getTargetUserId(); 4929 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 4930 && !alreadyTriedUserIds.get(targetUserId)) { 4931 // Checking if there are activities in the target user that can handle the 4932 // intent. 4933 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4934 flags, sourceUserId); 4935 if (resolveInfo != null) return resolveInfo; 4936 alreadyTriedUserIds.put(targetUserId, true); 4937 } 4938 } 4939 } 4940 return null; 4941 } 4942 checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, String resolvedType, int flags, int sourceUserId)4943 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 4944 String resolvedType, int flags, int sourceUserId) { 4945 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4946 resolvedType, flags, filter.getTargetUserId()); 4947 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 4948 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 4949 } 4950 return null; 4951 } 4952 createForwardingResolveInfo(IntentFilter filter, int sourceUserId, int targetUserId)4953 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 4954 int sourceUserId, int targetUserId) { 4955 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 4956 String className; 4957 if (targetUserId == UserHandle.USER_OWNER) { 4958 className = FORWARD_INTENT_TO_USER_OWNER; 4959 } else { 4960 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 4961 } 4962 ComponentName forwardingActivityComponentName = new ComponentName( 4963 mAndroidApplication.packageName, className); 4964 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 4965 sourceUserId); 4966 if (targetUserId == UserHandle.USER_OWNER) { 4967 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 4968 forwardingResolveInfo.noResourceId = true; 4969 } 4970 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 4971 forwardingResolveInfo.priority = 0; 4972 forwardingResolveInfo.preferredOrder = 0; 4973 forwardingResolveInfo.match = 0; 4974 forwardingResolveInfo.isDefault = true; 4975 forwardingResolveInfo.filter = filter; 4976 forwardingResolveInfo.targetUserId = targetUserId; 4977 return forwardingResolveInfo; 4978 } 4979 4980 @Override queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)4981 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 4982 Intent[] specifics, String[] specificTypes, Intent intent, 4983 String resolvedType, int flags, int userId) { 4984 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4985 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 4986 false, "query intent activity options"); 4987 final String resultsAction = intent.getAction(); 4988 4989 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 4990 | PackageManager.GET_RESOLVED_FILTER, userId); 4991 4992 if (DEBUG_INTENT_MATCHING) { 4993 Log.v(TAG, "Query " + intent + ": " + results); 4994 } 4995 4996 int specificsPos = 0; 4997 int N; 4998 4999 // todo: note that the algorithm used here is O(N^2). This 5000 // isn't a problem in our current environment, but if we start running 5001 // into situations where we have more than 5 or 10 matches then this 5002 // should probably be changed to something smarter... 5003 5004 // First we go through and resolve each of the specific items 5005 // that were supplied, taking care of removing any corresponding 5006 // duplicate items in the generic resolve list. 5007 if (specifics != null) { 5008 for (int i=0; i<specifics.length; i++) { 5009 final Intent sintent = specifics[i]; 5010 if (sintent == null) { 5011 continue; 5012 } 5013 5014 if (DEBUG_INTENT_MATCHING) { 5015 Log.v(TAG, "Specific #" + i + ": " + sintent); 5016 } 5017 5018 String action = sintent.getAction(); 5019 if (resultsAction != null && resultsAction.equals(action)) { 5020 // If this action was explicitly requested, then don't 5021 // remove things that have it. 5022 action = null; 5023 } 5024 5025 ResolveInfo ri = null; 5026 ActivityInfo ai = null; 5027 5028 ComponentName comp = sintent.getComponent(); 5029 if (comp == null) { 5030 ri = resolveIntent( 5031 sintent, 5032 specificTypes != null ? specificTypes[i] : null, 5033 flags, userId); 5034 if (ri == null) { 5035 continue; 5036 } 5037 if (ri == mResolveInfo) { 5038 // ACK! Must do something better with this. 5039 } 5040 ai = ri.activityInfo; 5041 comp = new ComponentName(ai.applicationInfo.packageName, 5042 ai.name); 5043 } else { 5044 ai = getActivityInfo(comp, flags, userId); 5045 if (ai == null) { 5046 continue; 5047 } 5048 } 5049 5050 // Look for any generic query activities that are duplicates 5051 // of this specific one, and remove them from the results. 5052 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5053 N = results.size(); 5054 int j; 5055 for (j=specificsPos; j<N; j++) { 5056 ResolveInfo sri = results.get(j); 5057 if ((sri.activityInfo.name.equals(comp.getClassName()) 5058 && sri.activityInfo.applicationInfo.packageName.equals( 5059 comp.getPackageName())) 5060 || (action != null && sri.filter.matchAction(action))) { 5061 results.remove(j); 5062 if (DEBUG_INTENT_MATCHING) Log.v( 5063 TAG, "Removing duplicate item from " + j 5064 + " due to specific " + specificsPos); 5065 if (ri == null) { 5066 ri = sri; 5067 } 5068 j--; 5069 N--; 5070 } 5071 } 5072 5073 // Add this specific item to its proper place. 5074 if (ri == null) { 5075 ri = new ResolveInfo(); 5076 ri.activityInfo = ai; 5077 } 5078 results.add(specificsPos, ri); 5079 ri.specificIndex = i; 5080 specificsPos++; 5081 } 5082 } 5083 5084 // Now we go through the remaining generic results and remove any 5085 // duplicate actions that are found here. 5086 N = results.size(); 5087 for (int i=specificsPos; i<N-1; i++) { 5088 final ResolveInfo rii = results.get(i); 5089 if (rii.filter == null) { 5090 continue; 5091 } 5092 5093 // Iterate over all of the actions of this result's intent 5094 // filter... typically this should be just one. 5095 final Iterator<String> it = rii.filter.actionsIterator(); 5096 if (it == null) { 5097 continue; 5098 } 5099 while (it.hasNext()) { 5100 final String action = it.next(); 5101 if (resultsAction != null && resultsAction.equals(action)) { 5102 // If this action was explicitly requested, then don't 5103 // remove things that have it. 5104 continue; 5105 } 5106 for (int j=i+1; j<N; j++) { 5107 final ResolveInfo rij = results.get(j); 5108 if (rij.filter != null && rij.filter.hasAction(action)) { 5109 results.remove(j); 5110 if (DEBUG_INTENT_MATCHING) Log.v( 5111 TAG, "Removing duplicate item from " + j 5112 + " due to action " + action + " at " + i); 5113 j--; 5114 N--; 5115 } 5116 } 5117 } 5118 5119 // If the caller didn't request filter information, drop it now 5120 // so we don't have to marshall/unmarshall it. 5121 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5122 rii.filter = null; 5123 } 5124 } 5125 5126 // Filter out the caller activity if so requested. 5127 if (caller != null) { 5128 N = results.size(); 5129 for (int i=0; i<N; i++) { 5130 ActivityInfo ainfo = results.get(i).activityInfo; 5131 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5132 && caller.getClassName().equals(ainfo.name)) { 5133 results.remove(i); 5134 break; 5135 } 5136 } 5137 } 5138 5139 // If the caller didn't request filter information, 5140 // drop them now so we don't have to 5141 // marshall/unmarshall it. 5142 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5143 N = results.size(); 5144 for (int i=0; i<N; i++) { 5145 results.get(i).filter = null; 5146 } 5147 } 5148 5149 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5150 return results; 5151 } 5152 5153 @Override queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)5154 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 5155 int userId) { 5156 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5157 ComponentName comp = intent.getComponent(); 5158 if (comp == null) { 5159 if (intent.getSelector() != null) { 5160 intent = intent.getSelector(); 5161 comp = intent.getComponent(); 5162 } 5163 } 5164 if (comp != null) { 5165 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5166 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5167 if (ai != null) { 5168 ResolveInfo ri = new ResolveInfo(); 5169 ri.activityInfo = ai; 5170 list.add(ri); 5171 } 5172 return list; 5173 } 5174 5175 // reader 5176 synchronized (mPackages) { 5177 String pkgName = intent.getPackage(); 5178 if (pkgName == null) { 5179 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5180 } 5181 final PackageParser.Package pkg = mPackages.get(pkgName); 5182 if (pkg != null) { 5183 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5184 userId); 5185 } 5186 return null; 5187 } 5188 } 5189 5190 @Override resolveService(Intent intent, String resolvedType, int flags, int userId)5191 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5192 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 5193 if (!sUserManager.exists(userId)) return null; 5194 if (query != null) { 5195 if (query.size() >= 1) { 5196 // If there is more than one service with the same priority, 5197 // just arbitrarily pick the first one. 5198 return query.get(0); 5199 } 5200 } 5201 return null; 5202 } 5203 5204 @Override queryIntentServices(Intent intent, String resolvedType, int flags, int userId)5205 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 5206 int userId) { 5207 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5208 ComponentName comp = intent.getComponent(); 5209 if (comp == null) { 5210 if (intent.getSelector() != null) { 5211 intent = intent.getSelector(); 5212 comp = intent.getComponent(); 5213 } 5214 } 5215 if (comp != null) { 5216 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5217 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5218 if (si != null) { 5219 final ResolveInfo ri = new ResolveInfo(); 5220 ri.serviceInfo = si; 5221 list.add(ri); 5222 } 5223 return list; 5224 } 5225 5226 // reader 5227 synchronized (mPackages) { 5228 String pkgName = intent.getPackage(); 5229 if (pkgName == null) { 5230 return mServices.queryIntent(intent, resolvedType, flags, userId); 5231 } 5232 final PackageParser.Package pkg = mPackages.get(pkgName); 5233 if (pkg != null) { 5234 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5235 userId); 5236 } 5237 return null; 5238 } 5239 } 5240 5241 @Override queryIntentContentProviders( Intent intent, String resolvedType, int flags, int userId)5242 public List<ResolveInfo> queryIntentContentProviders( 5243 Intent intent, String resolvedType, int flags, int userId) { 5244 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5245 ComponentName comp = intent.getComponent(); 5246 if (comp == null) { 5247 if (intent.getSelector() != null) { 5248 intent = intent.getSelector(); 5249 comp = intent.getComponent(); 5250 } 5251 } 5252 if (comp != null) { 5253 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5254 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5255 if (pi != null) { 5256 final ResolveInfo ri = new ResolveInfo(); 5257 ri.providerInfo = pi; 5258 list.add(ri); 5259 } 5260 return list; 5261 } 5262 5263 // reader 5264 synchronized (mPackages) { 5265 String pkgName = intent.getPackage(); 5266 if (pkgName == null) { 5267 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5268 } 5269 final PackageParser.Package pkg = mPackages.get(pkgName); 5270 if (pkg != null) { 5271 return mProviders.queryIntentForPackage( 5272 intent, resolvedType, flags, pkg.providers, userId); 5273 } 5274 return null; 5275 } 5276 } 5277 5278 @Override getInstalledPackages(int flags, int userId)5279 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5280 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5281 5282 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 5283 5284 // writer 5285 synchronized (mPackages) { 5286 ArrayList<PackageInfo> list; 5287 if (listUninstalled) { 5288 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5289 for (PackageSetting ps : mSettings.mPackages.values()) { 5290 PackageInfo pi; 5291 if (ps.pkg != null) { 5292 pi = generatePackageInfo(ps.pkg, flags, userId); 5293 } else { 5294 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5295 } 5296 if (pi != null) { 5297 list.add(pi); 5298 } 5299 } 5300 } else { 5301 list = new ArrayList<PackageInfo>(mPackages.size()); 5302 for (PackageParser.Package p : mPackages.values()) { 5303 PackageInfo pi = generatePackageInfo(p, flags, userId); 5304 if (pi != null) { 5305 list.add(pi); 5306 } 5307 } 5308 } 5309 5310 return new ParceledListSlice<PackageInfo>(list); 5311 } 5312 } 5313 addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)5314 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5315 String[] permissions, boolean[] tmp, int flags, int userId) { 5316 int numMatch = 0; 5317 final PermissionsState permissionsState = ps.getPermissionsState(); 5318 for (int i=0; i<permissions.length; i++) { 5319 final String permission = permissions[i]; 5320 if (permissionsState.hasPermission(permission, userId)) { 5321 tmp[i] = true; 5322 numMatch++; 5323 } else { 5324 tmp[i] = false; 5325 } 5326 } 5327 if (numMatch == 0) { 5328 return; 5329 } 5330 PackageInfo pi; 5331 if (ps.pkg != null) { 5332 pi = generatePackageInfo(ps.pkg, flags, userId); 5333 } else { 5334 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5335 } 5336 // The above might return null in cases of uninstalled apps or install-state 5337 // skew across users/profiles. 5338 if (pi != null) { 5339 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5340 if (numMatch == permissions.length) { 5341 pi.requestedPermissions = permissions; 5342 } else { 5343 pi.requestedPermissions = new String[numMatch]; 5344 numMatch = 0; 5345 for (int i=0; i<permissions.length; i++) { 5346 if (tmp[i]) { 5347 pi.requestedPermissions[numMatch] = permissions[i]; 5348 numMatch++; 5349 } 5350 } 5351 } 5352 } 5353 list.add(pi); 5354 } 5355 } 5356 5357 @Override getPackagesHoldingPermissions( String[] permissions, int flags, int userId)5358 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5359 String[] permissions, int flags, int userId) { 5360 if (!sUserManager.exists(userId)) return null; 5361 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5362 5363 // writer 5364 synchronized (mPackages) { 5365 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5366 boolean[] tmpBools = new boolean[permissions.length]; 5367 if (listUninstalled) { 5368 for (PackageSetting ps : mSettings.mPackages.values()) { 5369 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5370 } 5371 } else { 5372 for (PackageParser.Package pkg : mPackages.values()) { 5373 PackageSetting ps = (PackageSetting)pkg.mExtras; 5374 if (ps != null) { 5375 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5376 userId); 5377 } 5378 } 5379 } 5380 5381 return new ParceledListSlice<PackageInfo>(list); 5382 } 5383 } 5384 5385 @Override getInstalledApplications(int flags, int userId)5386 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 5387 if (!sUserManager.exists(userId)) return null; 5388 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 5389 5390 // writer 5391 synchronized (mPackages) { 5392 ArrayList<ApplicationInfo> list; 5393 if (listUninstalled) { 5394 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 5395 for (PackageSetting ps : mSettings.mPackages.values()) { 5396 ApplicationInfo ai; 5397 if (ps.pkg != null) { 5398 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 5399 ps.readUserState(userId), userId); 5400 } else { 5401 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 5402 } 5403 if (ai != null) { 5404 list.add(ai); 5405 } 5406 } 5407 } else { 5408 list = new ArrayList<ApplicationInfo>(mPackages.size()); 5409 for (PackageParser.Package p : mPackages.values()) { 5410 if (p.mExtras != null) { 5411 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5412 ((PackageSetting)p.mExtras).readUserState(userId), userId); 5413 if (ai != null) { 5414 list.add(ai); 5415 } 5416 } 5417 } 5418 } 5419 5420 return new ParceledListSlice<ApplicationInfo>(list); 5421 } 5422 } 5423 getPersistentApplications(int flags)5424 public List<ApplicationInfo> getPersistentApplications(int flags) { 5425 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 5426 5427 // reader 5428 synchronized (mPackages) { 5429 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 5430 final int userId = UserHandle.getCallingUserId(); 5431 while (i.hasNext()) { 5432 final PackageParser.Package p = i.next(); 5433 if (p.applicationInfo != null 5434 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 5435 && (!mSafeMode || isSystemApp(p))) { 5436 PackageSetting ps = mSettings.mPackages.get(p.packageName); 5437 if (ps != null) { 5438 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5439 ps.readUserState(userId), userId); 5440 if (ai != null) { 5441 finalList.add(ai); 5442 } 5443 } 5444 } 5445 } 5446 } 5447 5448 return finalList; 5449 } 5450 5451 @Override resolveContentProvider(String name, int flags, int userId)5452 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 5453 if (!sUserManager.exists(userId)) return null; 5454 // reader 5455 synchronized (mPackages) { 5456 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 5457 PackageSetting ps = provider != null 5458 ? mSettings.mPackages.get(provider.owner.packageName) 5459 : null; 5460 return ps != null 5461 && mSettings.isEnabledLPr(provider.info, flags, userId) 5462 && (!mSafeMode || (provider.info.applicationInfo.flags 5463 &ApplicationInfo.FLAG_SYSTEM) != 0) 5464 ? PackageParser.generateProviderInfo(provider, flags, 5465 ps.readUserState(userId), userId) 5466 : null; 5467 } 5468 } 5469 5470 /** 5471 * @deprecated 5472 */ 5473 @Deprecated querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)5474 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 5475 // reader 5476 synchronized (mPackages) { 5477 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 5478 .entrySet().iterator(); 5479 final int userId = UserHandle.getCallingUserId(); 5480 while (i.hasNext()) { 5481 Map.Entry<String, PackageParser.Provider> entry = i.next(); 5482 PackageParser.Provider p = entry.getValue(); 5483 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 5484 5485 if (ps != null && p.syncable 5486 && (!mSafeMode || (p.info.applicationInfo.flags 5487 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 5488 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 5489 ps.readUserState(userId), userId); 5490 if (info != null) { 5491 outNames.add(entry.getKey()); 5492 outInfo.add(info); 5493 } 5494 } 5495 } 5496 } 5497 } 5498 5499 @Override queryContentProviders(String processName, int uid, int flags)5500 public ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 5501 int uid, int flags) { 5502 ArrayList<ProviderInfo> finalList = null; 5503 // reader 5504 synchronized (mPackages) { 5505 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 5506 final int userId = processName != null ? 5507 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 5508 while (i.hasNext()) { 5509 final PackageParser.Provider p = i.next(); 5510 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 5511 if (ps != null && p.info.authority != null 5512 && (processName == null 5513 || (p.info.processName.equals(processName) 5514 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 5515 && mSettings.isEnabledLPr(p.info, flags, userId) 5516 && (!mSafeMode 5517 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 5518 if (finalList == null) { 5519 finalList = new ArrayList<ProviderInfo>(3); 5520 } 5521 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 5522 ps.readUserState(userId), userId); 5523 if (info != null) { 5524 finalList.add(info); 5525 } 5526 } 5527 } 5528 } 5529 5530 if (finalList != null) { 5531 Collections.sort(finalList, mProviderInitOrderSorter); 5532 return new ParceledListSlice<ProviderInfo>(finalList); 5533 } 5534 5535 return null; 5536 } 5537 5538 @Override getInstrumentationInfo(ComponentName name, int flags)5539 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 5540 int flags) { 5541 // reader 5542 synchronized (mPackages) { 5543 final PackageParser.Instrumentation i = mInstrumentation.get(name); 5544 return PackageParser.generateInstrumentationInfo(i, flags); 5545 } 5546 } 5547 5548 @Override queryInstrumentation(String targetPackage, int flags)5549 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 5550 int flags) { 5551 ArrayList<InstrumentationInfo> finalList = 5552 new ArrayList<InstrumentationInfo>(); 5553 5554 // reader 5555 synchronized (mPackages) { 5556 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 5557 while (i.hasNext()) { 5558 final PackageParser.Instrumentation p = i.next(); 5559 if (targetPackage == null 5560 || targetPackage.equals(p.info.targetPackage)) { 5561 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 5562 flags); 5563 if (ii != null) { 5564 finalList.add(ii); 5565 } 5566 } 5567 } 5568 } 5569 5570 return finalList; 5571 } 5572 createIdmapsForPackageLI(PackageParser.Package pkg)5573 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 5574 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 5575 if (overlays == null) { 5576 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 5577 return; 5578 } 5579 for (PackageParser.Package opkg : overlays.values()) { 5580 // Not much to do if idmap fails: we already logged the error 5581 // and we certainly don't want to abort installation of pkg simply 5582 // because an overlay didn't fit properly. For these reasons, 5583 // ignore the return value of createIdmapForPackagePairLI. 5584 createIdmapForPackagePairLI(pkg, opkg); 5585 } 5586 } 5587 createIdmapForPackagePairLI(PackageParser.Package pkg, PackageParser.Package opkg)5588 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 5589 PackageParser.Package opkg) { 5590 if (!opkg.mTrustedOverlay) { 5591 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 5592 opkg.baseCodePath + ": overlay not trusted"); 5593 return false; 5594 } 5595 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 5596 if (overlaySet == null) { 5597 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 5598 opkg.baseCodePath + " but target package has no known overlays"); 5599 return false; 5600 } 5601 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 5602 // TODO: generate idmap for split APKs 5603 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 5604 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 5605 + opkg.baseCodePath); 5606 return false; 5607 } 5608 PackageParser.Package[] overlayArray = 5609 overlaySet.values().toArray(new PackageParser.Package[0]); 5610 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 5611 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 5612 return p1.mOverlayPriority - p2.mOverlayPriority; 5613 } 5614 }; 5615 Arrays.sort(overlayArray, cmp); 5616 5617 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 5618 int i = 0; 5619 for (PackageParser.Package p : overlayArray) { 5620 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 5621 } 5622 return true; 5623 } 5624 scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime)5625 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 5626 final File[] files = dir.listFiles(); 5627 if (ArrayUtils.isEmpty(files)) { 5628 Log.d(TAG, "No files in app dir " + dir); 5629 return; 5630 } 5631 5632 if (DEBUG_PACKAGE_SCANNING) { 5633 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 5634 + " flags=0x" + Integer.toHexString(parseFlags)); 5635 } 5636 5637 for (File file : files) { 5638 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 5639 && !PackageInstallerService.isStageName(file.getName()); 5640 if (!isPackage) { 5641 // Ignore entries which are not packages 5642 continue; 5643 } 5644 try { 5645 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 5646 scanFlags, currentTime, null); 5647 } catch (PackageManagerException e) { 5648 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 5649 5650 // Delete invalid userdata apps 5651 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 5652 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 5653 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 5654 if (file.isDirectory()) { 5655 mInstaller.rmPackageDir(file.getAbsolutePath()); 5656 } else { 5657 file.delete(); 5658 } 5659 } 5660 } 5661 } 5662 } 5663 getSettingsProblemFile()5664 private static File getSettingsProblemFile() { 5665 File dataDir = Environment.getDataDirectory(); 5666 File systemDir = new File(dataDir, "system"); 5667 File fname = new File(systemDir, "uiderrors.txt"); 5668 return fname; 5669 } 5670 reportSettingsProblem(int priority, String msg)5671 static void reportSettingsProblem(int priority, String msg) { 5672 logCriticalInfo(priority, msg); 5673 } 5674 logCriticalInfo(int priority, String msg)5675 static void logCriticalInfo(int priority, String msg) { 5676 Slog.println(priority, TAG, msg); 5677 EventLogTags.writePmCriticalInfo(msg); 5678 try { 5679 File fname = getSettingsProblemFile(); 5680 FileOutputStream out = new FileOutputStream(fname, true); 5681 PrintWriter pw = new FastPrintWriter(out); 5682 SimpleDateFormat formatter = new SimpleDateFormat(); 5683 String dateString = formatter.format(new Date(System.currentTimeMillis())); 5684 pw.println(dateString + ": " + msg); 5685 pw.close(); 5686 FileUtils.setPermissions( 5687 fname.toString(), 5688 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 5689 -1, -1); 5690 } catch (java.io.IOException e) { 5691 } 5692 } 5693 collectCertificatesLI(PackageParser pp, PackageSetting ps, PackageParser.Package pkg, File srcFile, int parseFlags)5694 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 5695 PackageParser.Package pkg, File srcFile, int parseFlags) 5696 throws PackageManagerException { 5697 if (ps != null 5698 && ps.codePath.equals(srcFile) 5699 && ps.timeStamp == srcFile.lastModified() 5700 && !isCompatSignatureUpdateNeeded(pkg) 5701 && !isRecoverSignatureUpdateNeeded(pkg)) { 5702 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 5703 KeySetManagerService ksms = mSettings.mKeySetManagerService; 5704 ArraySet<PublicKey> signingKs; 5705 synchronized (mPackages) { 5706 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 5707 } 5708 if (ps.signatures.mSignatures != null 5709 && ps.signatures.mSignatures.length != 0 5710 && signingKs != null) { 5711 // Optimization: reuse the existing cached certificates 5712 // if the package appears to be unchanged. 5713 pkg.mSignatures = ps.signatures.mSignatures; 5714 pkg.mSigningKeys = signingKs; 5715 return; 5716 } 5717 5718 Slog.w(TAG, "PackageSetting for " + ps.name 5719 + " is missing signatures. Collecting certs again to recover them."); 5720 } else { 5721 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 5722 } 5723 5724 try { 5725 pp.collectCertificates(pkg, parseFlags); 5726 pp.collectManifestDigest(pkg); 5727 } catch (PackageParserException e) { 5728 throw PackageManagerException.from(e); 5729 } 5730 } 5731 5732 /* 5733 * Scan a package and return the newly parsed package. 5734 * Returns null in case of errors and the error code is stored in mLastScanError 5735 */ scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)5736 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 5737 long currentTime, UserHandle user) throws PackageManagerException { 5738 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 5739 parseFlags |= mDefParseFlags; 5740 PackageParser pp = new PackageParser(); 5741 pp.setSeparateProcesses(mSeparateProcesses); 5742 pp.setOnlyCoreApps(mOnlyCore); 5743 pp.setDisplayMetrics(mMetrics); 5744 5745 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 5746 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 5747 } 5748 5749 final PackageParser.Package pkg; 5750 try { 5751 pkg = pp.parsePackage(scanFile, parseFlags); 5752 } catch (PackageParserException e) { 5753 throw PackageManagerException.from(e); 5754 } 5755 5756 PackageSetting ps = null; 5757 PackageSetting updatedPkg; 5758 // reader 5759 synchronized (mPackages) { 5760 // Look to see if we already know about this package. 5761 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 5762 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 5763 // This package has been renamed to its original name. Let's 5764 // use that. 5765 ps = mSettings.peekPackageLPr(oldName); 5766 } 5767 // If there was no original package, see one for the real package name. 5768 if (ps == null) { 5769 ps = mSettings.peekPackageLPr(pkg.packageName); 5770 } 5771 // Check to see if this package could be hiding/updating a system 5772 // package. Must look for it either under the original or real 5773 // package name depending on our state. 5774 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 5775 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 5776 } 5777 boolean updatedPkgBetter = false; 5778 // First check if this is a system package that may involve an update 5779 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5780 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 5781 // it needs to drop FLAG_PRIVILEGED. 5782 if (locationIsPrivileged(scanFile)) { 5783 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5784 } else { 5785 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5786 } 5787 5788 if (ps != null && !ps.codePath.equals(scanFile)) { 5789 // The path has changed from what was last scanned... check the 5790 // version of the new path against what we have stored to determine 5791 // what to do. 5792 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 5793 if (pkg.mVersionCode <= ps.versionCode) { 5794 // The system package has been updated and the code path does not match 5795 // Ignore entry. Skip it. 5796 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 5797 + " ignored: updated version " + ps.versionCode 5798 + " better than this " + pkg.mVersionCode); 5799 if (!updatedPkg.codePath.equals(scanFile)) { 5800 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 5801 + ps.name + " changing from " + updatedPkg.codePathString 5802 + " to " + scanFile); 5803 updatedPkg.codePath = scanFile; 5804 updatedPkg.codePathString = scanFile.toString(); 5805 updatedPkg.resourcePath = scanFile; 5806 updatedPkg.resourcePathString = scanFile.toString(); 5807 } 5808 updatedPkg.pkg = pkg; 5809 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5810 "Package " + ps.name + " at " + scanFile 5811 + " ignored: updated version " + ps.versionCode 5812 + " better than this " + pkg.mVersionCode); 5813 } else { 5814 // The current app on the system partition is better than 5815 // what we have updated to on the data partition; switch 5816 // back to the system partition version. 5817 // At this point, its safely assumed that package installation for 5818 // apps in system partition will go through. If not there won't be a working 5819 // version of the app 5820 // writer 5821 synchronized (mPackages) { 5822 // Just remove the loaded entries from package lists. 5823 mPackages.remove(ps.name); 5824 } 5825 5826 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5827 + " reverting from " + ps.codePathString 5828 + ": new version " + pkg.mVersionCode 5829 + " better than installed " + ps.versionCode); 5830 5831 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5832 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5833 synchronized (mInstallLock) { 5834 args.cleanUpResourcesLI(); 5835 } 5836 synchronized (mPackages) { 5837 mSettings.enableSystemPackageLPw(ps.name); 5838 } 5839 updatedPkgBetter = true; 5840 } 5841 } 5842 } 5843 5844 if (updatedPkg != null) { 5845 // An updated system app will not have the PARSE_IS_SYSTEM flag set 5846 // initially 5847 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 5848 5849 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 5850 // flag set initially 5851 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 5852 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 5853 } 5854 } 5855 5856 // Verify certificates against what was last scanned 5857 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 5858 5859 /* 5860 * A new system app appeared, but we already had a non-system one of the 5861 * same name installed earlier. 5862 */ 5863 boolean shouldHideSystemApp = false; 5864 if (updatedPkg == null && ps != null 5865 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 5866 /* 5867 * Check to make sure the signatures match first. If they don't, 5868 * wipe the installed application and its data. 5869 */ 5870 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 5871 != PackageManager.SIGNATURE_MATCH) { 5872 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 5873 + " signatures don't match existing userdata copy; removing"); 5874 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 5875 ps = null; 5876 } else { 5877 /* 5878 * If the newly-added system app is an older version than the 5879 * already installed version, hide it. It will be scanned later 5880 * and re-added like an update. 5881 */ 5882 if (pkg.mVersionCode <= ps.versionCode) { 5883 shouldHideSystemApp = true; 5884 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 5885 + " but new version " + pkg.mVersionCode + " better than installed " 5886 + ps.versionCode + "; hiding system"); 5887 } else { 5888 /* 5889 * The newly found system app is a newer version that the 5890 * one previously installed. Simply remove the 5891 * already-installed application and replace it with our own 5892 * while keeping the application data. 5893 */ 5894 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5895 + " reverting from " + ps.codePathString + ": new version " 5896 + pkg.mVersionCode + " better than installed " + ps.versionCode); 5897 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5898 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5899 synchronized (mInstallLock) { 5900 args.cleanUpResourcesLI(); 5901 } 5902 } 5903 } 5904 } 5905 5906 // The apk is forward locked (not public) if its code and resources 5907 // are kept in different files. (except for app in either system or 5908 // vendor path). 5909 // TODO grab this value from PackageSettings 5910 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5911 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 5912 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 5913 } 5914 } 5915 5916 // TODO: extend to support forward-locked splits 5917 String resourcePath = null; 5918 String baseResourcePath = null; 5919 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 5920 if (ps != null && ps.resourcePathString != null) { 5921 resourcePath = ps.resourcePathString; 5922 baseResourcePath = ps.resourcePathString; 5923 } else { 5924 // Should not happen at all. Just log an error. 5925 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 5926 } 5927 } else { 5928 resourcePath = pkg.codePath; 5929 baseResourcePath = pkg.baseCodePath; 5930 } 5931 5932 // Set application objects path explicitly. 5933 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 5934 pkg.applicationInfo.setCodePath(pkg.codePath); 5935 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 5936 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 5937 pkg.applicationInfo.setResourcePath(resourcePath); 5938 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 5939 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 5940 5941 // Note that we invoke the following method only if we are about to unpack an application 5942 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 5943 | SCAN_UPDATE_SIGNATURE, currentTime, user); 5944 5945 /* 5946 * If the system app should be overridden by a previously installed 5947 * data, hide the system app now and let the /data/app scan pick it up 5948 * again. 5949 */ 5950 if (shouldHideSystemApp) { 5951 synchronized (mPackages) { 5952 mSettings.disableSystemPackageLPw(pkg.packageName); 5953 } 5954 } 5955 5956 return scannedPkg; 5957 } 5958 fixProcessName(String defProcessName, String processName, int uid)5959 private static String fixProcessName(String defProcessName, 5960 String processName, int uid) { 5961 if (processName == null) { 5962 return defProcessName; 5963 } 5964 return processName; 5965 } 5966 verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)5967 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 5968 throws PackageManagerException { 5969 if (pkgSetting.signatures.mSignatures != null) { 5970 // Already existing package. Make sure signatures match 5971 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 5972 == PackageManager.SIGNATURE_MATCH; 5973 if (!match) { 5974 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 5975 == PackageManager.SIGNATURE_MATCH; 5976 } 5977 if (!match) { 5978 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 5979 == PackageManager.SIGNATURE_MATCH; 5980 } 5981 if (!match) { 5982 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5983 + pkg.packageName + " signatures do not match the " 5984 + "previously installed version; ignoring!"); 5985 } 5986 } 5987 5988 // Check for shared user signatures 5989 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 5990 // Already existing package. Make sure signatures match 5991 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5992 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 5993 if (!match) { 5994 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 5995 == PackageManager.SIGNATURE_MATCH; 5996 } 5997 if (!match) { 5998 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 5999 == PackageManager.SIGNATURE_MATCH; 6000 } 6001 if (!match) { 6002 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6003 "Package " + pkg.packageName 6004 + " has no signatures that match those in shared user " 6005 + pkgSetting.sharedUser.name + "; ignoring!"); 6006 } 6007 } 6008 } 6009 6010 /** 6011 * Enforces that only the system UID or root's UID can call a method exposed 6012 * via Binder. 6013 * 6014 * @param message used as message if SecurityException is thrown 6015 * @throws SecurityException if the caller is not system or root 6016 */ enforceSystemOrRoot(String message)6017 private static final void enforceSystemOrRoot(String message) { 6018 final int uid = Binder.getCallingUid(); 6019 if (uid != Process.SYSTEM_UID && uid != 0) { 6020 throw new SecurityException(message); 6021 } 6022 } 6023 6024 @Override performBootDexOpt()6025 public void performBootDexOpt() { 6026 enforceSystemOrRoot("Only the system can request dexopt be performed"); 6027 6028 // Before everything else, see whether we need to fstrim. 6029 try { 6030 IMountService ms = PackageHelper.getMountService(); 6031 if (ms != null) { 6032 final boolean isUpgrade = isUpgrade(); 6033 boolean doTrim = isUpgrade; 6034 if (doTrim) { 6035 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6036 } else { 6037 final long interval = android.provider.Settings.Global.getLong( 6038 mContext.getContentResolver(), 6039 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6040 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6041 if (interval > 0) { 6042 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6043 if (timeSinceLast > interval) { 6044 doTrim = true; 6045 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6046 + "; running immediately"); 6047 } 6048 } 6049 } 6050 if (doTrim) { 6051 if (!isFirstBoot()) { 6052 try { 6053 ActivityManagerNative.getDefault().showBootMessage( 6054 mContext.getResources().getString( 6055 R.string.android_upgrading_fstrim), true); 6056 } catch (RemoteException e) { 6057 } 6058 } 6059 ms.runMaintenance(); 6060 } 6061 } else { 6062 Slog.e(TAG, "Mount service unavailable!"); 6063 } 6064 } catch (RemoteException e) { 6065 // Can't happen; MountService is local 6066 } 6067 6068 final ArraySet<PackageParser.Package> pkgs; 6069 synchronized (mPackages) { 6070 pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages(); 6071 } 6072 6073 if (pkgs != null) { 6074 // Sort apps by importance for dexopt ordering. Important apps are given more priority 6075 // in case the device runs out of space. 6076 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 6077 // Give priority to core apps. 6078 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6079 PackageParser.Package pkg = it.next(); 6080 if (pkg.coreApp) { 6081 if (DEBUG_DEXOPT) { 6082 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 6083 } 6084 sortedPkgs.add(pkg); 6085 it.remove(); 6086 } 6087 } 6088 // Give priority to system apps that listen for pre boot complete. 6089 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 6090 ArraySet<String> pkgNames = getPackageNamesForIntent(intent); 6091 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 6092 PackageParser.Package pkg = it.next(); 6093 if (pkgNames.contains(pkg.packageName)) { 6094 if (DEBUG_DEXOPT) { 6095 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 6096 } 6097 sortedPkgs.add(pkg); 6098 it.remove(); 6099 } 6100 } 6101 // Filter out packages that aren't recently used. 6102 filterRecentlyUsedApps(pkgs); 6103 // Add all remaining apps. 6104 for (PackageParser.Package pkg : pkgs) { 6105 if (DEBUG_DEXOPT) { 6106 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 6107 } 6108 sortedPkgs.add(pkg); 6109 } 6110 6111 // If we want to be lazy, filter everything that wasn't recently used. 6112 if (mLazyDexOpt) { 6113 filterRecentlyUsedApps(sortedPkgs); 6114 } 6115 6116 int i = 0; 6117 int total = sortedPkgs.size(); 6118 File dataDir = Environment.getDataDirectory(); 6119 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 6120 if (lowThreshold == 0) { 6121 throw new IllegalStateException("Invalid low memory threshold"); 6122 } 6123 for (PackageParser.Package pkg : sortedPkgs) { 6124 long usableSpace = dataDir.getUsableSpace(); 6125 if (usableSpace < lowThreshold) { 6126 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 6127 break; 6128 } 6129 performBootDexOpt(pkg, ++i, total); 6130 } 6131 } 6132 } 6133 filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs)6134 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 6135 // Filter out packages that aren't recently used. 6136 // 6137 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 6138 // should do a full dexopt. 6139 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 6140 int total = pkgs.size(); 6141 int skipped = 0; 6142 long now = System.currentTimeMillis(); 6143 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 6144 PackageParser.Package pkg = i.next(); 6145 long then = pkg.mLastPackageUsageTimeInMills; 6146 if (then + mDexOptLRUThresholdInMills < now) { 6147 if (DEBUG_DEXOPT) { 6148 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 6149 ((then == 0) ? "never" : new Date(then))); 6150 } 6151 i.remove(); 6152 skipped++; 6153 } 6154 } 6155 if (DEBUG_DEXOPT) { 6156 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 6157 } 6158 } 6159 } 6160 getPackageNamesForIntent(Intent intent)6161 private ArraySet<String> getPackageNamesForIntent(Intent intent) { 6162 List<ResolveInfo> ris = null; 6163 try { 6164 ris = AppGlobals.getPackageManager().queryIntentReceivers( 6165 intent, null, 0, UserHandle.USER_OWNER); 6166 } catch (RemoteException e) { 6167 } 6168 ArraySet<String> pkgNames = new ArraySet<String>(); 6169 if (ris != null) { 6170 for (ResolveInfo ri : ris) { 6171 pkgNames.add(ri.activityInfo.packageName); 6172 } 6173 } 6174 return pkgNames; 6175 } 6176 performBootDexOpt(PackageParser.Package pkg, int curr, int total)6177 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 6178 if (DEBUG_DEXOPT) { 6179 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 6180 } 6181 if (!isFirstBoot()) { 6182 try { 6183 ActivityManagerNative.getDefault().showBootMessage( 6184 mContext.getResources().getString(R.string.android_upgrading_apk, 6185 curr, total), true); 6186 } catch (RemoteException e) { 6187 } 6188 } 6189 PackageParser.Package p = pkg; 6190 synchronized (mInstallLock) { 6191 mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, 6192 false /* force dex */, false /* defer */, true /* include dependencies */, 6193 false /* boot complete */); 6194 } 6195 } 6196 6197 @Override performDexOptIfNeeded(String packageName, String instructionSet)6198 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6199 return performDexOpt(packageName, instructionSet, false); 6200 } 6201 performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt)6202 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) { 6203 boolean dexopt = mLazyDexOpt || backgroundDexopt; 6204 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 6205 if (!dexopt && !updateUsage) { 6206 // We aren't going to dexopt or update usage, so bail early. 6207 return false; 6208 } 6209 PackageParser.Package p; 6210 final String targetInstructionSet; 6211 synchronized (mPackages) { 6212 p = mPackages.get(packageName); 6213 if (p == null) { 6214 return false; 6215 } 6216 if (updateUsage) { 6217 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6218 } 6219 mPackageUsage.write(false); 6220 if (!dexopt) { 6221 // We aren't going to dexopt, so bail early. 6222 return false; 6223 } 6224 6225 targetInstructionSet = instructionSet != null ? instructionSet : 6226 getPrimaryInstructionSet(p.applicationInfo); 6227 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 6228 return false; 6229 } 6230 } 6231 long callingId = Binder.clearCallingIdentity(); 6232 try { 6233 synchronized (mInstallLock) { 6234 final String[] instructionSets = new String[] { targetInstructionSet }; 6235 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, 6236 false /* forceDex */, false /* defer */, true /* inclDependencies */, 6237 true /* boot complete */); 6238 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 6239 } 6240 } finally { 6241 Binder.restoreCallingIdentity(callingId); 6242 } 6243 } 6244 getPackagesThatNeedDexOpt()6245 public ArraySet<String> getPackagesThatNeedDexOpt() { 6246 ArraySet<String> pkgs = null; 6247 synchronized (mPackages) { 6248 for (PackageParser.Package p : mPackages.values()) { 6249 if (DEBUG_DEXOPT) { 6250 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 6251 } 6252 if (!p.mDexOptPerformed.isEmpty()) { 6253 continue; 6254 } 6255 if (pkgs == null) { 6256 pkgs = new ArraySet<String>(); 6257 } 6258 pkgs.add(p.packageName); 6259 } 6260 } 6261 return pkgs; 6262 } 6263 shutdown()6264 public void shutdown() { 6265 mPackageUsage.write(true); 6266 } 6267 6268 @Override forceDexOpt(String packageName)6269 public void forceDexOpt(String packageName) { 6270 enforceSystemOrRoot("forceDexOpt"); 6271 6272 PackageParser.Package pkg; 6273 synchronized (mPackages) { 6274 pkg = mPackages.get(packageName); 6275 if (pkg == null) { 6276 throw new IllegalArgumentException("Missing package: " + packageName); 6277 } 6278 } 6279 6280 synchronized (mInstallLock) { 6281 final String[] instructionSets = new String[] { 6282 getPrimaryInstructionSet(pkg.applicationInfo) }; 6283 final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, 6284 true /*forceDex*/, false /* defer */, true /* inclDependencies */, 6285 true /* boot complete */); 6286 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 6287 throw new IllegalStateException("Failed to dexopt: " + res); 6288 } 6289 } 6290 } 6291 verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)6292 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 6293 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6294 Slog.w(TAG, "Unable to update from " + oldPkg.name 6295 + " to " + newPkg.packageName 6296 + ": old package not in system partition"); 6297 return false; 6298 } else if (mPackages.get(oldPkg.name) != null) { 6299 Slog.w(TAG, "Unable to update from " + oldPkg.name 6300 + " to " + newPkg.packageName 6301 + ": old package still exists"); 6302 return false; 6303 } 6304 return true; 6305 } 6306 createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo)6307 private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) { 6308 int[] users = sUserManager.getUserIds(); 6309 int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo); 6310 if (res < 0) { 6311 return res; 6312 } 6313 for (int user : users) { 6314 if (user != 0) { 6315 res = mInstaller.createUserData(volumeUuid, packageName, 6316 UserHandle.getUid(user, uid), user, seinfo); 6317 if (res < 0) { 6318 return res; 6319 } 6320 } 6321 } 6322 return res; 6323 } 6324 removeDataDirsLI(String volumeUuid, String packageName)6325 private int removeDataDirsLI(String volumeUuid, String packageName) { 6326 int[] users = sUserManager.getUserIds(); 6327 int res = 0; 6328 for (int user : users) { 6329 int resInner = mInstaller.remove(volumeUuid, packageName, user); 6330 if (resInner < 0) { 6331 res = resInner; 6332 } 6333 } 6334 6335 return res; 6336 } 6337 deleteCodeCacheDirsLI(String volumeUuid, String packageName)6338 private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 6339 int[] users = sUserManager.getUserIds(); 6340 int res = 0; 6341 for (int user : users) { 6342 int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user); 6343 if (resInner < 0) { 6344 res = resInner; 6345 } 6346 } 6347 return res; 6348 } 6349 addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, PackageParser.Package changingLib)6350 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 6351 PackageParser.Package changingLib) { 6352 if (file.path != null) { 6353 usesLibraryFiles.add(file.path); 6354 return; 6355 } 6356 PackageParser.Package p = mPackages.get(file.apk); 6357 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 6358 // If we are doing this while in the middle of updating a library apk, 6359 // then we need to make sure to use that new apk for determining the 6360 // dependencies here. (We haven't yet finished committing the new apk 6361 // to the package manager state.) 6362 if (p == null || p.packageName.equals(changingLib.packageName)) { 6363 p = changingLib; 6364 } 6365 } 6366 if (p != null) { 6367 usesLibraryFiles.addAll(p.getAllCodePaths()); 6368 } 6369 } 6370 updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)6371 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 6372 PackageParser.Package changingLib) throws PackageManagerException { 6373 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 6374 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 6375 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 6376 for (int i=0; i<N; i++) { 6377 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 6378 if (file == null) { 6379 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 6380 "Package " + pkg.packageName + " requires unavailable shared library " 6381 + pkg.usesLibraries.get(i) + "; failing!"); 6382 } 6383 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 6384 } 6385 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 6386 for (int i=0; i<N; i++) { 6387 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 6388 if (file == null) { 6389 Slog.w(TAG, "Package " + pkg.packageName 6390 + " desires unavailable shared library " 6391 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 6392 } else { 6393 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 6394 } 6395 } 6396 N = usesLibraryFiles.size(); 6397 if (N > 0) { 6398 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 6399 } else { 6400 pkg.usesLibraryFiles = null; 6401 } 6402 } 6403 } 6404 hasString(List<String> list, List<String> which)6405 private static boolean hasString(List<String> list, List<String> which) { 6406 if (list == null) { 6407 return false; 6408 } 6409 for (int i=list.size()-1; i>=0; i--) { 6410 for (int j=which.size()-1; j>=0; j--) { 6411 if (which.get(j).equals(list.get(i))) { 6412 return true; 6413 } 6414 } 6415 } 6416 return false; 6417 } 6418 updateAllSharedLibrariesLPw()6419 private void updateAllSharedLibrariesLPw() { 6420 for (PackageParser.Package pkg : mPackages.values()) { 6421 try { 6422 updateSharedLibrariesLPw(pkg, null); 6423 } catch (PackageManagerException e) { 6424 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 6425 } 6426 } 6427 } 6428 updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)6429 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 6430 PackageParser.Package changingPkg) { 6431 ArrayList<PackageParser.Package> res = null; 6432 for (PackageParser.Package pkg : mPackages.values()) { 6433 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 6434 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 6435 if (res == null) { 6436 res = new ArrayList<PackageParser.Package>(); 6437 } 6438 res.add(pkg); 6439 try { 6440 updateSharedLibrariesLPw(pkg, changingPkg); 6441 } catch (PackageManagerException e) { 6442 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 6443 } 6444 } 6445 } 6446 return res; 6447 } 6448 6449 /** 6450 * Derive the value of the {@code cpuAbiOverride} based on the provided 6451 * value and an optional stored value from the package settings. 6452 */ deriveAbiOverride(String abiOverride, PackageSetting settings)6453 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 6454 String cpuAbiOverride = null; 6455 6456 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 6457 cpuAbiOverride = null; 6458 } else if (abiOverride != null) { 6459 cpuAbiOverride = abiOverride; 6460 } else if (settings != null) { 6461 cpuAbiOverride = settings.cpuAbiOverrideString; 6462 } 6463 6464 return cpuAbiOverride; 6465 } 6466 scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)6467 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 6468 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6469 boolean success = false; 6470 try { 6471 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 6472 currentTime, user); 6473 success = true; 6474 return res; 6475 } finally { 6476 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 6477 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 6478 } 6479 } 6480 } 6481 scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)6482 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 6483 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6484 final File scanFile = new File(pkg.codePath); 6485 if (pkg.applicationInfo.getCodePath() == null || 6486 pkg.applicationInfo.getResourcePath() == null) { 6487 // Bail out. The resource and code paths haven't been set. 6488 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 6489 "Code and resource paths haven't been set correctly"); 6490 } 6491 6492 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 6493 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 6494 } else { 6495 // Only allow system apps to be flagged as core apps. 6496 pkg.coreApp = false; 6497 } 6498 6499 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 6500 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6501 } 6502 6503 if (mCustomResolverComponentName != null && 6504 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 6505 setUpCustomResolverActivity(pkg); 6506 } 6507 6508 if (pkg.packageName.equals("android")) { 6509 synchronized (mPackages) { 6510 if (mAndroidApplication != null) { 6511 Slog.w(TAG, "*************************************************"); 6512 Slog.w(TAG, "Core android package being redefined. Skipping."); 6513 Slog.w(TAG, " file=" + scanFile); 6514 Slog.w(TAG, "*************************************************"); 6515 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 6516 "Core android package being redefined. Skipping."); 6517 } 6518 6519 // Set up information for our fall-back user intent resolution activity. 6520 mPlatformPackage = pkg; 6521 pkg.mVersionCode = mSdkVersion; 6522 mAndroidApplication = pkg.applicationInfo; 6523 6524 if (!mResolverReplaced) { 6525 mResolveActivity.applicationInfo = mAndroidApplication; 6526 mResolveActivity.name = ResolverActivity.class.getName(); 6527 mResolveActivity.packageName = mAndroidApplication.packageName; 6528 mResolveActivity.processName = "system:ui"; 6529 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6530 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 6531 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 6532 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 6533 mResolveActivity.exported = true; 6534 mResolveActivity.enabled = true; 6535 mResolveInfo.activityInfo = mResolveActivity; 6536 mResolveInfo.priority = 0; 6537 mResolveInfo.preferredOrder = 0; 6538 mResolveInfo.match = 0; 6539 mResolveComponentName = new ComponentName( 6540 mAndroidApplication.packageName, mResolveActivity.name); 6541 } 6542 } 6543 } 6544 6545 if (DEBUG_PACKAGE_SCANNING) { 6546 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6547 Log.d(TAG, "Scanning package " + pkg.packageName); 6548 } 6549 6550 if (mPackages.containsKey(pkg.packageName) 6551 || mSharedLibraries.containsKey(pkg.packageName)) { 6552 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 6553 "Application package " + pkg.packageName 6554 + " already installed. Skipping duplicate."); 6555 } 6556 6557 // If we're only installing presumed-existing packages, require that the 6558 // scanned APK is both already known and at the path previously established 6559 // for it. Previously unknown packages we pick up normally, but if we have an 6560 // a priori expectation about this package's install presence, enforce it. 6561 // With a singular exception for new system packages. When an OTA contains 6562 // a new system package, we allow the codepath to change from a system location 6563 // to the user-installed location. If we don't allow this change, any newer, 6564 // user-installed version of the application will be ignored. 6565 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 6566 if (mExpectingBetter.containsKey(pkg.packageName)) { 6567 logCriticalInfo(Log.WARN, 6568 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 6569 } else { 6570 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 6571 if (known != null) { 6572 if (DEBUG_PACKAGE_SCANNING) { 6573 Log.d(TAG, "Examining " + pkg.codePath 6574 + " and requiring known paths " + known.codePathString 6575 + " & " + known.resourcePathString); 6576 } 6577 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 6578 || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { 6579 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 6580 "Application package " + pkg.packageName 6581 + " found at " + pkg.applicationInfo.getCodePath() 6582 + " but expected at " + known.codePathString + "; ignoring."); 6583 } 6584 } 6585 } 6586 } 6587 6588 // Initialize package source and resource directories 6589 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 6590 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 6591 6592 SharedUserSetting suid = null; 6593 PackageSetting pkgSetting = null; 6594 6595 if (!isSystemApp(pkg)) { 6596 // Only system apps can use these features. 6597 pkg.mOriginalPackages = null; 6598 pkg.mRealPackage = null; 6599 pkg.mAdoptPermissions = null; 6600 } 6601 6602 // writer 6603 synchronized (mPackages) { 6604 if (pkg.mSharedUserId != null) { 6605 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 6606 if (suid == null) { 6607 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6608 "Creating application package " + pkg.packageName 6609 + " for shared user failed"); 6610 } 6611 if (DEBUG_PACKAGE_SCANNING) { 6612 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6613 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 6614 + "): packages=" + suid.packages); 6615 } 6616 } 6617 6618 // Check if we are renaming from an original package name. 6619 PackageSetting origPackage = null; 6620 String realName = null; 6621 if (pkg.mOriginalPackages != null) { 6622 // This package may need to be renamed to a previously 6623 // installed name. Let's check on that... 6624 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 6625 if (pkg.mOriginalPackages.contains(renamed)) { 6626 // This package had originally been installed as the 6627 // original name, and we have already taken care of 6628 // transitioning to the new one. Just update the new 6629 // one to continue using the old name. 6630 realName = pkg.mRealPackage; 6631 if (!pkg.packageName.equals(renamed)) { 6632 // Callers into this function may have already taken 6633 // care of renaming the package; only do it here if 6634 // it is not already done. 6635 pkg.setPackageName(renamed); 6636 } 6637 6638 } else { 6639 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 6640 if ((origPackage = mSettings.peekPackageLPr( 6641 pkg.mOriginalPackages.get(i))) != null) { 6642 // We do have the package already installed under its 6643 // original name... should we use it? 6644 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 6645 // New package is not compatible with original. 6646 origPackage = null; 6647 continue; 6648 } else if (origPackage.sharedUser != null) { 6649 // Make sure uid is compatible between packages. 6650 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 6651 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 6652 + " to " + pkg.packageName + ": old uid " 6653 + origPackage.sharedUser.name 6654 + " differs from " + pkg.mSharedUserId); 6655 origPackage = null; 6656 continue; 6657 } 6658 } else { 6659 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 6660 + pkg.packageName + " to old name " + origPackage.name); 6661 } 6662 break; 6663 } 6664 } 6665 } 6666 } 6667 6668 if (mTransferedPackages.contains(pkg.packageName)) { 6669 Slog.w(TAG, "Package " + pkg.packageName 6670 + " was transferred to another, but its .apk remains"); 6671 } 6672 6673 // Just create the setting, don't add it yet. For already existing packages 6674 // the PkgSetting exists already and doesn't have to be created. 6675 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 6676 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 6677 pkg.applicationInfo.primaryCpuAbi, 6678 pkg.applicationInfo.secondaryCpuAbi, 6679 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 6680 user, false); 6681 if (pkgSetting == null) { 6682 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6683 "Creating application package " + pkg.packageName + " failed"); 6684 } 6685 6686 if (pkgSetting.origPackage != null) { 6687 // If we are first transitioning from an original package, 6688 // fix up the new package's name now. We need to do this after 6689 // looking up the package under its new name, so getPackageLP 6690 // can take care of fiddling things correctly. 6691 pkg.setPackageName(origPackage.name); 6692 6693 // File a report about this. 6694 String msg = "New package " + pkgSetting.realName 6695 + " renamed to replace old package " + pkgSetting.name; 6696 reportSettingsProblem(Log.WARN, msg); 6697 6698 // Make a note of it. 6699 mTransferedPackages.add(origPackage.name); 6700 6701 // No longer need to retain this. 6702 pkgSetting.origPackage = null; 6703 } 6704 6705 if (realName != null) { 6706 // Make a note of it. 6707 mTransferedPackages.add(pkg.packageName); 6708 } 6709 6710 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 6711 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 6712 } 6713 6714 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6715 // Check all shared libraries and map to their actual file path. 6716 // We only do this here for apps not on a system dir, because those 6717 // are the only ones that can fail an install due to this. We 6718 // will take care of the system apps by updating all of their 6719 // library paths after the scan is done. 6720 updateSharedLibrariesLPw(pkg, null); 6721 } 6722 6723 if (mFoundPolicyFile) { 6724 SELinuxMMAC.assignSeinfoValue(pkg); 6725 } 6726 6727 pkg.applicationInfo.uid = pkgSetting.appId; 6728 pkg.mExtras = pkgSetting; 6729 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 6730 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 6731 // We just determined the app is signed correctly, so bring 6732 // over the latest parsed certs. 6733 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6734 } else { 6735 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6736 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6737 "Package " + pkg.packageName + " upgrade keys do not match the " 6738 + "previously installed version"); 6739 } else { 6740 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6741 String msg = "System package " + pkg.packageName 6742 + " signature changed; retaining data."; 6743 reportSettingsProblem(Log.WARN, msg); 6744 } 6745 } 6746 } else { 6747 try { 6748 verifySignaturesLP(pkgSetting, pkg); 6749 // We just determined the app is signed correctly, so bring 6750 // over the latest parsed certs. 6751 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6752 } catch (PackageManagerException e) { 6753 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6754 throw e; 6755 } 6756 // The signature has changed, but this package is in the system 6757 // image... let's recover! 6758 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6759 // However... if this package is part of a shared user, but it 6760 // doesn't match the signature of the shared user, let's fail. 6761 // What this means is that you can't change the signatures 6762 // associated with an overall shared user, which doesn't seem all 6763 // that unreasonable. 6764 if (pkgSetting.sharedUser != null) { 6765 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6766 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 6767 throw new PackageManagerException( 6768 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 6769 "Signature mismatch for shared user : " 6770 + pkgSetting.sharedUser); 6771 } 6772 } 6773 // File a report about this. 6774 String msg = "System package " + pkg.packageName 6775 + " signature changed; retaining data."; 6776 reportSettingsProblem(Log.WARN, msg); 6777 } 6778 } 6779 // Verify that this new package doesn't have any content providers 6780 // that conflict with existing packages. Only do this if the 6781 // package isn't already installed, since we don't want to break 6782 // things that are installed. 6783 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 6784 final int N = pkg.providers.size(); 6785 int i; 6786 for (i=0; i<N; i++) { 6787 PackageParser.Provider p = pkg.providers.get(i); 6788 if (p.info.authority != null) { 6789 String names[] = p.info.authority.split(";"); 6790 for (int j = 0; j < names.length; j++) { 6791 if (mProvidersByAuthority.containsKey(names[j])) { 6792 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6793 final String otherPackageName = 6794 ((other != null && other.getComponentName() != null) ? 6795 other.getComponentName().getPackageName() : "?"); 6796 throw new PackageManagerException( 6797 INSTALL_FAILED_CONFLICTING_PROVIDER, 6798 "Can't install because provider name " + names[j] 6799 + " (in package " + pkg.applicationInfo.packageName 6800 + ") is already used by " + otherPackageName); 6801 } 6802 } 6803 } 6804 } 6805 } 6806 6807 if (pkg.mAdoptPermissions != null) { 6808 // This package wants to adopt ownership of permissions from 6809 // another package. 6810 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 6811 final String origName = pkg.mAdoptPermissions.get(i); 6812 final PackageSetting orig = mSettings.peekPackageLPr(origName); 6813 if (orig != null) { 6814 if (verifyPackageUpdateLPr(orig, pkg)) { 6815 Slog.i(TAG, "Adopting permissions from " + origName + " to " 6816 + pkg.packageName); 6817 mSettings.transferPermissionsLPw(origName, pkg.packageName); 6818 } 6819 } 6820 } 6821 } 6822 } 6823 6824 final String pkgName = pkg.packageName; 6825 6826 final long scanFileTime = scanFile.lastModified(); 6827 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 6828 pkg.applicationInfo.processName = fixProcessName( 6829 pkg.applicationInfo.packageName, 6830 pkg.applicationInfo.processName, 6831 pkg.applicationInfo.uid); 6832 6833 File dataPath; 6834 if (mPlatformPackage == pkg) { 6835 // The system package is special. 6836 dataPath = new File(Environment.getDataDirectory(), "system"); 6837 6838 pkg.applicationInfo.dataDir = dataPath.getPath(); 6839 6840 } else { 6841 // This is a normal package, need to make its data directory. 6842 dataPath = Environment.getDataUserPackageDirectory(pkg.volumeUuid, 6843 UserHandle.USER_OWNER, pkg.packageName); 6844 6845 boolean uidError = false; 6846 if (dataPath.exists()) { 6847 int currentUid = 0; 6848 try { 6849 StructStat stat = Os.stat(dataPath.getPath()); 6850 currentUid = stat.st_uid; 6851 } catch (ErrnoException e) { 6852 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 6853 } 6854 6855 // If we have mismatched owners for the data path, we have a problem. 6856 if (currentUid != pkg.applicationInfo.uid) { 6857 boolean recovered = false; 6858 if (currentUid == 0) { 6859 // The directory somehow became owned by root. Wow. 6860 // This is probably because the system was stopped while 6861 // installd was in the middle of messing with its libs 6862 // directory. Ask installd to fix that. 6863 int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName, 6864 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 6865 if (ret >= 0) { 6866 recovered = true; 6867 String msg = "Package " + pkg.packageName 6868 + " unexpectedly changed to uid 0; recovered to " + 6869 + pkg.applicationInfo.uid; 6870 reportSettingsProblem(Log.WARN, msg); 6871 } 6872 } 6873 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6874 || (scanFlags&SCAN_BOOTING) != 0)) { 6875 // If this is a system app, we can at least delete its 6876 // current data so the application will still work. 6877 int ret = removeDataDirsLI(pkg.volumeUuid, pkgName); 6878 if (ret >= 0) { 6879 // TODO: Kill the processes first 6880 // Old data gone! 6881 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6882 ? "System package " : "Third party package "; 6883 String msg = prefix + pkg.packageName 6884 + " has changed from uid: " 6885 + currentUid + " to " 6886 + pkg.applicationInfo.uid + "; old data erased"; 6887 reportSettingsProblem(Log.WARN, msg); 6888 recovered = true; 6889 6890 // And now re-install the app. 6891 ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6892 pkg.applicationInfo.seinfo); 6893 if (ret == -1) { 6894 // Ack should not happen! 6895 msg = prefix + pkg.packageName 6896 + " could not have data directory re-created after delete."; 6897 reportSettingsProblem(Log.WARN, msg); 6898 throw new PackageManagerException( 6899 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 6900 } 6901 } 6902 if (!recovered) { 6903 mHasSystemUidErrors = true; 6904 } 6905 } else if (!recovered) { 6906 // If we allow this install to proceed, we will be broken. 6907 // Abort, abort! 6908 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 6909 "scanPackageLI"); 6910 } 6911 if (!recovered) { 6912 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 6913 + pkg.applicationInfo.uid + "/fs_" 6914 + currentUid; 6915 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 6916 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 6917 String msg = "Package " + pkg.packageName 6918 + " has mismatched uid: " 6919 + currentUid + " on disk, " 6920 + pkg.applicationInfo.uid + " in settings"; 6921 // writer 6922 synchronized (mPackages) { 6923 mSettings.mReadMessages.append(msg); 6924 mSettings.mReadMessages.append('\n'); 6925 uidError = true; 6926 if (!pkgSetting.uidError) { 6927 reportSettingsProblem(Log.ERROR, msg); 6928 } 6929 } 6930 } 6931 } 6932 pkg.applicationInfo.dataDir = dataPath.getPath(); 6933 if (mShouldRestoreconData) { 6934 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 6935 mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName, 6936 pkg.applicationInfo.seinfo, pkg.applicationInfo.uid); 6937 } 6938 } else { 6939 if (DEBUG_PACKAGE_SCANNING) { 6940 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6941 Log.v(TAG, "Want this data dir: " + dataPath); 6942 } 6943 //invoke installer to do the actual installation 6944 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6945 pkg.applicationInfo.seinfo); 6946 if (ret < 0) { 6947 // Error from installer 6948 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6949 "Unable to create data dirs [errorCode=" + ret + "]"); 6950 } 6951 6952 if (dataPath.exists()) { 6953 pkg.applicationInfo.dataDir = dataPath.getPath(); 6954 } else { 6955 Slog.w(TAG, "Unable to create data directory: " + dataPath); 6956 pkg.applicationInfo.dataDir = null; 6957 } 6958 } 6959 6960 pkgSetting.uidError = uidError; 6961 } 6962 6963 final String path = scanFile.getPath(); 6964 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 6965 6966 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 6967 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 6968 6969 // Some system apps still use directory structure for native libraries 6970 // in which case we might end up not detecting abi solely based on apk 6971 // structure. Try to detect abi based on directory structure. 6972 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 6973 pkg.applicationInfo.primaryCpuAbi == null) { 6974 setBundledAppAbisAndRoots(pkg, pkgSetting); 6975 setNativeLibraryPaths(pkg); 6976 } 6977 6978 } else { 6979 if ((scanFlags & SCAN_MOVE) != 0) { 6980 // We haven't run dex-opt for this move (since we've moved the compiled output too) 6981 // but we already have this packages package info in the PackageSetting. We just 6982 // use that and derive the native library path based on the new codepath. 6983 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 6984 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 6985 } 6986 6987 // Set native library paths again. For moves, the path will be updated based on the 6988 // ABIs we've determined above. For non-moves, the path will be updated based on the 6989 // ABIs we determined during compilation, but the path will depend on the final 6990 // package path (after the rename away from the stage path). 6991 setNativeLibraryPaths(pkg); 6992 } 6993 6994 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 6995 final int[] userIds = sUserManager.getUserIds(); 6996 synchronized (mInstallLock) { 6997 // Make sure all user data directories are ready to roll; we're okay 6998 // if they already exist 6999 if (!TextUtils.isEmpty(pkg.volumeUuid)) { 7000 for (int userId : userIds) { 7001 if (userId != 0) { 7002 mInstaller.createUserData(pkg.volumeUuid, pkg.packageName, 7003 UserHandle.getUid(userId, pkg.applicationInfo.uid), userId, 7004 pkg.applicationInfo.seinfo); 7005 } 7006 } 7007 } 7008 7009 // Create a native library symlink only if we have native libraries 7010 // and if the native libraries are 32 bit libraries. We do not provide 7011 // this symlink for 64 bit libraries. 7012 if (pkg.applicationInfo.primaryCpuAbi != null && 7013 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 7014 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 7015 for (int userId : userIds) { 7016 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 7017 nativeLibPath, userId) < 0) { 7018 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 7019 "Failed linking native library dir (user=" + userId + ")"); 7020 } 7021 } 7022 } 7023 } 7024 7025 // This is a special case for the "system" package, where the ABI is 7026 // dictated by the zygote configuration (and init.rc). We should keep track 7027 // of this ABI so that we can deal with "normal" applications that run under 7028 // the same UID correctly. 7029 if (mPlatformPackage == pkg) { 7030 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7031 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7032 } 7033 7034 // If there's a mismatch between the abi-override in the package setting 7035 // and the abiOverride specified for the install. Warn about this because we 7036 // would've already compiled the app without taking the package setting into 7037 // account. 7038 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7039 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7040 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7041 " for package: " + pkg.packageName); 7042 } 7043 } 7044 7045 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7046 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7047 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7048 7049 // Copy the derived override back to the parsed package, so that we can 7050 // update the package settings accordingly. 7051 pkg.cpuAbiOverride = cpuAbiOverride; 7052 7053 if (DEBUG_ABI_SELECTION) { 7054 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7055 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7056 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7057 } 7058 7059 // Push the derived path down into PackageSettings so we know what to 7060 // clean up at uninstall time. 7061 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7062 7063 if (DEBUG_ABI_SELECTION) { 7064 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7065 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7066 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7067 } 7068 7069 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7070 // We don't do this here during boot because we can do it all 7071 // at once after scanning all existing packages. 7072 // 7073 // We also do this *before* we perform dexopt on this package, so that 7074 // we can avoid redundant dexopts, and also to make sure we've got the 7075 // code and package path correct. 7076 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7077 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, true /* boot complete */); 7078 } 7079 7080 if ((scanFlags & SCAN_NO_DEX) == 0) { 7081 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, 7082 forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */, 7083 (scanFlags & SCAN_BOOTING) == 0); 7084 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7085 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 7086 } 7087 } 7088 if (mFactoryTest && pkg.requestedPermissions.contains( 7089 android.Manifest.permission.FACTORY_TEST)) { 7090 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7091 } 7092 7093 ArrayList<PackageParser.Package> clientLibPkgs = null; 7094 7095 // writer 7096 synchronized (mPackages) { 7097 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7098 // Only system apps can add new shared libraries. 7099 if (pkg.libraryNames != null) { 7100 for (int i=0; i<pkg.libraryNames.size(); i++) { 7101 String name = pkg.libraryNames.get(i); 7102 boolean allowed = false; 7103 if (pkg.isUpdatedSystemApp()) { 7104 // New library entries can only be added through the 7105 // system image. This is important to get rid of a lot 7106 // of nasty edge cases: for example if we allowed a non- 7107 // system update of the app to add a library, then uninstalling 7108 // the update would make the library go away, and assumptions 7109 // we made such as through app install filtering would now 7110 // have allowed apps on the device which aren't compatible 7111 // with it. Better to just have the restriction here, be 7112 // conservative, and create many fewer cases that can negatively 7113 // impact the user experience. 7114 final PackageSetting sysPs = mSettings 7115 .getDisabledSystemPkgLPr(pkg.packageName); 7116 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 7117 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 7118 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 7119 allowed = true; 7120 allowed = true; 7121 break; 7122 } 7123 } 7124 } 7125 } else { 7126 allowed = true; 7127 } 7128 if (allowed) { 7129 if (!mSharedLibraries.containsKey(name)) { 7130 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 7131 } else if (!name.equals(pkg.packageName)) { 7132 Slog.w(TAG, "Package " + pkg.packageName + " library " 7133 + name + " already exists; skipping"); 7134 } 7135 } else { 7136 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 7137 + name + " that is not declared on system image; skipping"); 7138 } 7139 } 7140 if ((scanFlags&SCAN_BOOTING) == 0) { 7141 // If we are not booting, we need to update any applications 7142 // that are clients of our shared library. If we are booting, 7143 // this will all be done once the scan is complete. 7144 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 7145 } 7146 } 7147 } 7148 } 7149 7150 // We also need to dexopt any apps that are dependent on this library. Note that 7151 // if these fail, we should abort the install since installing the library will 7152 // result in some apps being broken. 7153 if (clientLibPkgs != null) { 7154 if ((scanFlags & SCAN_NO_DEX) == 0) { 7155 for (int i = 0; i < clientLibPkgs.size(); i++) { 7156 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7157 int result = mPackageDexOptimizer.performDexOpt(clientPkg, 7158 null /* instruction sets */, forceDex, 7159 (scanFlags & SCAN_DEFER_DEX) != 0, false, 7160 (scanFlags & SCAN_BOOTING) == 0); 7161 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7162 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 7163 "scanPackageLI failed to dexopt clientLibPkgs"); 7164 } 7165 } 7166 } 7167 } 7168 7169 // Request the ActivityManager to kill the process(only for existing packages) 7170 // so that we do not end up in a confused state while the user is still using the older 7171 // version of the application while the new one gets installed. 7172 if ((scanFlags & SCAN_REPLACING) != 0) { 7173 killApplication(pkg.applicationInfo.packageName, 7174 pkg.applicationInfo.uid, "replace pkg"); 7175 } 7176 7177 // Also need to kill any apps that are dependent on the library. 7178 if (clientLibPkgs != null) { 7179 for (int i=0; i<clientLibPkgs.size(); i++) { 7180 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7181 killApplication(clientPkg.applicationInfo.packageName, 7182 clientPkg.applicationInfo.uid, "update lib"); 7183 } 7184 } 7185 7186 // Make sure we're not adding any bogus keyset info 7187 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7188 ksms.assertScannedPackageValid(pkg); 7189 7190 // writer 7191 synchronized (mPackages) { 7192 // We don't expect installation to fail beyond this point 7193 7194 // Add the new setting to mSettings 7195 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 7196 // Add the new setting to mPackages 7197 mPackages.put(pkg.applicationInfo.packageName, pkg); 7198 // Make sure we don't accidentally delete its data. 7199 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 7200 while (iter.hasNext()) { 7201 PackageCleanItem item = iter.next(); 7202 if (pkgName.equals(item.packageName)) { 7203 iter.remove(); 7204 } 7205 } 7206 7207 // Take care of first install / last update times. 7208 if (currentTime != 0) { 7209 if (pkgSetting.firstInstallTime == 0) { 7210 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 7211 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 7212 pkgSetting.lastUpdateTime = currentTime; 7213 } 7214 } else if (pkgSetting.firstInstallTime == 0) { 7215 // We need *something*. Take time time stamp of the file. 7216 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 7217 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 7218 if (scanFileTime != pkgSetting.timeStamp) { 7219 // A package on the system image has changed; consider this 7220 // to be an update. 7221 pkgSetting.lastUpdateTime = scanFileTime; 7222 } 7223 } 7224 7225 // Add the package's KeySets to the global KeySetManagerService 7226 ksms.addScannedPackageLPw(pkg); 7227 7228 int N = pkg.providers.size(); 7229 StringBuilder r = null; 7230 int i; 7231 for (i=0; i<N; i++) { 7232 PackageParser.Provider p = pkg.providers.get(i); 7233 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 7234 p.info.processName, pkg.applicationInfo.uid); 7235 mProviders.addProvider(p); 7236 p.syncable = p.info.isSyncable; 7237 if (p.info.authority != null) { 7238 String names[] = p.info.authority.split(";"); 7239 p.info.authority = null; 7240 for (int j = 0; j < names.length; j++) { 7241 if (j == 1 && p.syncable) { 7242 // We only want the first authority for a provider to possibly be 7243 // syncable, so if we already added this provider using a different 7244 // authority clear the syncable flag. We copy the provider before 7245 // changing it because the mProviders object contains a reference 7246 // to a provider that we don't want to change. 7247 // Only do this for the second authority since the resulting provider 7248 // object can be the same for all future authorities for this provider. 7249 p = new PackageParser.Provider(p); 7250 p.syncable = false; 7251 } 7252 if (!mProvidersByAuthority.containsKey(names[j])) { 7253 mProvidersByAuthority.put(names[j], p); 7254 if (p.info.authority == null) { 7255 p.info.authority = names[j]; 7256 } else { 7257 p.info.authority = p.info.authority + ";" + names[j]; 7258 } 7259 if (DEBUG_PACKAGE_SCANNING) { 7260 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7261 Log.d(TAG, "Registered content provider: " + names[j] 7262 + ", className = " + p.info.name + ", isSyncable = " 7263 + p.info.isSyncable); 7264 } 7265 } else { 7266 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7267 Slog.w(TAG, "Skipping provider name " + names[j] + 7268 " (in package " + pkg.applicationInfo.packageName + 7269 "): name already used by " 7270 + ((other != null && other.getComponentName() != null) 7271 ? other.getComponentName().getPackageName() : "?")); 7272 } 7273 } 7274 } 7275 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7276 if (r == null) { 7277 r = new StringBuilder(256); 7278 } else { 7279 r.append(' '); 7280 } 7281 r.append(p.info.name); 7282 } 7283 } 7284 if (r != null) { 7285 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 7286 } 7287 7288 N = pkg.services.size(); 7289 r = null; 7290 for (i=0; i<N; i++) { 7291 PackageParser.Service s = pkg.services.get(i); 7292 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 7293 s.info.processName, pkg.applicationInfo.uid); 7294 mServices.addService(s); 7295 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7296 if (r == null) { 7297 r = new StringBuilder(256); 7298 } else { 7299 r.append(' '); 7300 } 7301 r.append(s.info.name); 7302 } 7303 } 7304 if (r != null) { 7305 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 7306 } 7307 7308 N = pkg.receivers.size(); 7309 r = null; 7310 for (i=0; i<N; i++) { 7311 PackageParser.Activity a = pkg.receivers.get(i); 7312 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 7313 a.info.processName, pkg.applicationInfo.uid); 7314 mReceivers.addActivity(a, "receiver"); 7315 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7316 if (r == null) { 7317 r = new StringBuilder(256); 7318 } else { 7319 r.append(' '); 7320 } 7321 r.append(a.info.name); 7322 } 7323 } 7324 if (r != null) { 7325 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 7326 } 7327 7328 N = pkg.activities.size(); 7329 r = null; 7330 for (i=0; i<N; i++) { 7331 PackageParser.Activity a = pkg.activities.get(i); 7332 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 7333 a.info.processName, pkg.applicationInfo.uid); 7334 mActivities.addActivity(a, "activity"); 7335 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7336 if (r == null) { 7337 r = new StringBuilder(256); 7338 } else { 7339 r.append(' '); 7340 } 7341 r.append(a.info.name); 7342 } 7343 } 7344 if (r != null) { 7345 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 7346 } 7347 7348 N = pkg.permissionGroups.size(); 7349 r = null; 7350 for (i=0; i<N; i++) { 7351 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 7352 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 7353 if (cur == null) { 7354 mPermissionGroups.put(pg.info.name, pg); 7355 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7356 if (r == null) { 7357 r = new StringBuilder(256); 7358 } else { 7359 r.append(' '); 7360 } 7361 r.append(pg.info.name); 7362 } 7363 } else { 7364 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 7365 + pg.info.packageName + " ignored: original from " 7366 + cur.info.packageName); 7367 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7368 if (r == null) { 7369 r = new StringBuilder(256); 7370 } else { 7371 r.append(' '); 7372 } 7373 r.append("DUP:"); 7374 r.append(pg.info.name); 7375 } 7376 } 7377 } 7378 if (r != null) { 7379 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 7380 } 7381 7382 N = pkg.permissions.size(); 7383 r = null; 7384 for (i=0; i<N; i++) { 7385 PackageParser.Permission p = pkg.permissions.get(i); 7386 7387 // Assume by default that we did not install this permission into the system. 7388 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 7389 7390 // Now that permission groups have a special meaning, we ignore permission 7391 // groups for legacy apps to prevent unexpected behavior. In particular, 7392 // permissions for one app being granted to someone just becuase they happen 7393 // to be in a group defined by another app (before this had no implications). 7394 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 7395 p.group = mPermissionGroups.get(p.info.group); 7396 // Warn for a permission in an unknown group. 7397 if (p.info.group != null && p.group == null) { 7398 Slog.w(TAG, "Permission " + p.info.name + " from package " 7399 + p.info.packageName + " in an unknown group " + p.info.group); 7400 } 7401 } 7402 7403 ArrayMap<String, BasePermission> permissionMap = 7404 p.tree ? mSettings.mPermissionTrees 7405 : mSettings.mPermissions; 7406 BasePermission bp = permissionMap.get(p.info.name); 7407 7408 // Allow system apps to redefine non-system permissions 7409 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 7410 final boolean currentOwnerIsSystem = (bp.perm != null 7411 && isSystemApp(bp.perm.owner)); 7412 if (isSystemApp(p.owner)) { 7413 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 7414 // It's a built-in permission and no owner, take ownership now 7415 bp.packageSetting = pkgSetting; 7416 bp.perm = p; 7417 bp.uid = pkg.applicationInfo.uid; 7418 bp.sourcePackage = p.info.packageName; 7419 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 7420 } else if (!currentOwnerIsSystem) { 7421 String msg = "New decl " + p.owner + " of permission " 7422 + p.info.name + " is system; overriding " + bp.sourcePackage; 7423 reportSettingsProblem(Log.WARN, msg); 7424 bp = null; 7425 } 7426 } 7427 } 7428 7429 if (bp == null) { 7430 bp = new BasePermission(p.info.name, p.info.packageName, 7431 BasePermission.TYPE_NORMAL); 7432 permissionMap.put(p.info.name, bp); 7433 } 7434 7435 if (bp.perm == null) { 7436 if (bp.sourcePackage == null 7437 || bp.sourcePackage.equals(p.info.packageName)) { 7438 BasePermission tree = findPermissionTreeLP(p.info.name); 7439 if (tree == null 7440 || tree.sourcePackage.equals(p.info.packageName)) { 7441 bp.packageSetting = pkgSetting; 7442 bp.perm = p; 7443 bp.uid = pkg.applicationInfo.uid; 7444 bp.sourcePackage = p.info.packageName; 7445 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 7446 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7447 if (r == null) { 7448 r = new StringBuilder(256); 7449 } else { 7450 r.append(' '); 7451 } 7452 r.append(p.info.name); 7453 } 7454 } else { 7455 Slog.w(TAG, "Permission " + p.info.name + " from package " 7456 + p.info.packageName + " ignored: base tree " 7457 + tree.name + " is from package " 7458 + tree.sourcePackage); 7459 } 7460 } else { 7461 Slog.w(TAG, "Permission " + p.info.name + " from package " 7462 + p.info.packageName + " ignored: original from " 7463 + bp.sourcePackage); 7464 } 7465 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7466 if (r == null) { 7467 r = new StringBuilder(256); 7468 } else { 7469 r.append(' '); 7470 } 7471 r.append("DUP:"); 7472 r.append(p.info.name); 7473 } 7474 if (bp.perm == p) { 7475 bp.protectionLevel = p.info.protectionLevel; 7476 } 7477 } 7478 7479 if (r != null) { 7480 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 7481 } 7482 7483 N = pkg.instrumentation.size(); 7484 r = null; 7485 for (i=0; i<N; i++) { 7486 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 7487 a.info.packageName = pkg.applicationInfo.packageName; 7488 a.info.sourceDir = pkg.applicationInfo.sourceDir; 7489 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 7490 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 7491 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 7492 a.info.dataDir = pkg.applicationInfo.dataDir; 7493 7494 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 7495 // need other information about the application, like the ABI and what not ? 7496 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 7497 mInstrumentation.put(a.getComponentName(), a); 7498 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 7499 if (r == null) { 7500 r = new StringBuilder(256); 7501 } else { 7502 r.append(' '); 7503 } 7504 r.append(a.info.name); 7505 } 7506 } 7507 if (r != null) { 7508 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 7509 } 7510 7511 if (pkg.protectedBroadcasts != null) { 7512 N = pkg.protectedBroadcasts.size(); 7513 for (i=0; i<N; i++) { 7514 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 7515 } 7516 } 7517 7518 pkgSetting.setTimeStamp(scanFileTime); 7519 7520 // Create idmap files for pairs of (packages, overlay packages). 7521 // Note: "android", ie framework-res.apk, is handled by native layers. 7522 if (pkg.mOverlayTarget != null) { 7523 // This is an overlay package. 7524 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 7525 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 7526 mOverlays.put(pkg.mOverlayTarget, 7527 new ArrayMap<String, PackageParser.Package>()); 7528 } 7529 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 7530 map.put(pkg.packageName, pkg); 7531 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 7532 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 7533 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7534 "scanPackageLI failed to createIdmap"); 7535 } 7536 } 7537 } else if (mOverlays.containsKey(pkg.packageName) && 7538 !pkg.packageName.equals("android")) { 7539 // This is a regular package, with one or more known overlay packages. 7540 createIdmapsForPackageLI(pkg); 7541 } 7542 } 7543 7544 return pkg; 7545 } 7546 7547 /** 7548 * Derive the ABI of a non-system package located at {@code scanFile}. This information 7549 * is derived purely on the basis of the contents of {@code scanFile} and 7550 * {@code cpuAbiOverride}. 7551 * 7552 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 7553 */ derivePackageAbi(PackageParser.Package pkg, File scanFile, String cpuAbiOverride, boolean extractLibs)7554 public void derivePackageAbi(PackageParser.Package pkg, File scanFile, 7555 String cpuAbiOverride, boolean extractLibs) 7556 throws PackageManagerException { 7557 // TODO: We can probably be smarter about this stuff. For installed apps, 7558 // we can calculate this information at install time once and for all. For 7559 // system apps, we can probably assume that this information doesn't change 7560 // after the first boot scan. As things stand, we do lots of unnecessary work. 7561 7562 // Give ourselves some initial paths; we'll come back for another 7563 // pass once we've determined ABI below. 7564 setNativeLibraryPaths(pkg); 7565 7566 // We would never need to extract libs for forward-locked and external packages, 7567 // since the container service will do it for us. We shouldn't attempt to 7568 // extract libs from system app when it was not updated. 7569 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 7570 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 7571 extractLibs = false; 7572 } 7573 7574 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 7575 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 7576 7577 NativeLibraryHelper.Handle handle = null; 7578 try { 7579 handle = NativeLibraryHelper.Handle.create(scanFile); 7580 // TODO(multiArch): This can be null for apps that didn't go through the 7581 // usual installation process. We can calculate it again, like we 7582 // do during install time. 7583 // 7584 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 7585 // unnecessary. 7586 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 7587 7588 // Null out the abis so that they can be recalculated. 7589 pkg.applicationInfo.primaryCpuAbi = null; 7590 pkg.applicationInfo.secondaryCpuAbi = null; 7591 if (isMultiArch(pkg.applicationInfo)) { 7592 // Warn if we've set an abiOverride for multi-lib packages.. 7593 // By definition, we need to copy both 32 and 64 bit libraries for 7594 // such packages. 7595 if (pkg.cpuAbiOverride != null 7596 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 7597 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 7598 } 7599 7600 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 7601 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 7602 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 7603 if (extractLibs) { 7604 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7605 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 7606 useIsaSpecificSubdirs); 7607 } else { 7608 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 7609 } 7610 } 7611 7612 maybeThrowExceptionForMultiArchCopy( 7613 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 7614 7615 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 7616 if (extractLibs) { 7617 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7618 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 7619 useIsaSpecificSubdirs); 7620 } else { 7621 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 7622 } 7623 } 7624 7625 maybeThrowExceptionForMultiArchCopy( 7626 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 7627 7628 if (abi64 >= 0) { 7629 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 7630 } 7631 7632 if (abi32 >= 0) { 7633 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 7634 if (abi64 >= 0) { 7635 pkg.applicationInfo.secondaryCpuAbi = abi; 7636 } else { 7637 pkg.applicationInfo.primaryCpuAbi = abi; 7638 } 7639 } 7640 } else { 7641 String[] abiList = (cpuAbiOverride != null) ? 7642 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 7643 7644 // Enable gross and lame hacks for apps that are built with old 7645 // SDK tools. We must scan their APKs for renderscript bitcode and 7646 // not launch them if it's present. Don't bother checking on devices 7647 // that don't have 64 bit support. 7648 boolean needsRenderScriptOverride = false; 7649 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 7650 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 7651 abiList = Build.SUPPORTED_32_BIT_ABIS; 7652 needsRenderScriptOverride = true; 7653 } 7654 7655 final int copyRet; 7656 if (extractLibs) { 7657 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7658 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 7659 } else { 7660 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 7661 } 7662 7663 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 7664 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 7665 "Error unpackaging native libs for app, errorCode=" + copyRet); 7666 } 7667 7668 if (copyRet >= 0) { 7669 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 7670 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 7671 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 7672 } else if (needsRenderScriptOverride) { 7673 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 7674 } 7675 } 7676 } catch (IOException ioe) { 7677 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 7678 } finally { 7679 IoUtils.closeQuietly(handle); 7680 } 7681 7682 // Now that we've calculated the ABIs and determined if it's an internal app, 7683 // we will go ahead and populate the nativeLibraryPath. 7684 setNativeLibraryPaths(pkg); 7685 } 7686 7687 /** 7688 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 7689 * i.e, so that all packages can be run inside a single process if required. 7690 * 7691 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 7692 * this function will either try and make the ABI for all packages in {@code packagesForUser} 7693 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 7694 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 7695 * updating a package that belongs to a shared user. 7696 * 7697 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 7698 * adds unnecessary complexity. 7699 */ adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt, boolean bootComplete)7700 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 7701 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt, 7702 boolean bootComplete) { 7703 String requiredInstructionSet = null; 7704 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 7705 requiredInstructionSet = VMRuntime.getInstructionSet( 7706 scannedPackage.applicationInfo.primaryCpuAbi); 7707 } 7708 7709 PackageSetting requirer = null; 7710 for (PackageSetting ps : packagesForUser) { 7711 // If packagesForUser contains scannedPackage, we skip it. This will happen 7712 // when scannedPackage is an update of an existing package. Without this check, 7713 // we will never be able to change the ABI of any package belonging to a shared 7714 // user, even if it's compatible with other packages. 7715 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7716 if (ps.primaryCpuAbiString == null) { 7717 continue; 7718 } 7719 7720 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 7721 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 7722 // We have a mismatch between instruction sets (say arm vs arm64) warn about 7723 // this but there's not much we can do. 7724 String errorMessage = "Instruction set mismatch, " 7725 + ((requirer == null) ? "[caller]" : requirer) 7726 + " requires " + requiredInstructionSet + " whereas " + ps 7727 + " requires " + instructionSet; 7728 Slog.w(TAG, errorMessage); 7729 } 7730 7731 if (requiredInstructionSet == null) { 7732 requiredInstructionSet = instructionSet; 7733 requirer = ps; 7734 } 7735 } 7736 } 7737 7738 if (requiredInstructionSet != null) { 7739 String adjustedAbi; 7740 if (requirer != null) { 7741 // requirer != null implies that either scannedPackage was null or that scannedPackage 7742 // did not require an ABI, in which case we have to adjust scannedPackage to match 7743 // the ABI of the set (which is the same as requirer's ABI) 7744 adjustedAbi = requirer.primaryCpuAbiString; 7745 if (scannedPackage != null) { 7746 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 7747 } 7748 } else { 7749 // requirer == null implies that we're updating all ABIs in the set to 7750 // match scannedPackage. 7751 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 7752 } 7753 7754 for (PackageSetting ps : packagesForUser) { 7755 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7756 if (ps.primaryCpuAbiString != null) { 7757 continue; 7758 } 7759 7760 ps.primaryCpuAbiString = adjustedAbi; 7761 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 7762 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 7763 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 7764 7765 int result = mPackageDexOptimizer.performDexOpt(ps.pkg, 7766 null /* instruction sets */, forceDexOpt, deferDexOpt, true, 7767 bootComplete); 7768 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7769 ps.primaryCpuAbiString = null; 7770 ps.pkg.applicationInfo.primaryCpuAbi = null; 7771 return; 7772 } else { 7773 mInstaller.rmdex(ps.codePathString, 7774 getDexCodeInstructionSet(getPreferredInstructionSet())); 7775 } 7776 } 7777 } 7778 } 7779 } 7780 } 7781 setUpCustomResolverActivity(PackageParser.Package pkg)7782 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 7783 synchronized (mPackages) { 7784 mResolverReplaced = true; 7785 // Set up information for custom user intent resolution activity. 7786 mResolveActivity.applicationInfo = pkg.applicationInfo; 7787 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 7788 mResolveActivity.packageName = pkg.applicationInfo.packageName; 7789 mResolveActivity.processName = pkg.applicationInfo.packageName; 7790 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7791 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 7792 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 7793 mResolveActivity.theme = 0; 7794 mResolveActivity.exported = true; 7795 mResolveActivity.enabled = true; 7796 mResolveInfo.activityInfo = mResolveActivity; 7797 mResolveInfo.priority = 0; 7798 mResolveInfo.preferredOrder = 0; 7799 mResolveInfo.match = 0; 7800 mResolveComponentName = mCustomResolverComponentName; 7801 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 7802 mResolveComponentName); 7803 } 7804 } 7805 calculateBundledApkRoot(final String codePathString)7806 private static String calculateBundledApkRoot(final String codePathString) { 7807 final File codePath = new File(codePathString); 7808 final File codeRoot; 7809 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 7810 codeRoot = Environment.getRootDirectory(); 7811 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 7812 codeRoot = Environment.getOemDirectory(); 7813 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 7814 codeRoot = Environment.getVendorDirectory(); 7815 } else { 7816 // Unrecognized code path; take its top real segment as the apk root: 7817 // e.g. /something/app/blah.apk => /something 7818 try { 7819 File f = codePath.getCanonicalFile(); 7820 File parent = f.getParentFile(); // non-null because codePath is a file 7821 File tmp; 7822 while ((tmp = parent.getParentFile()) != null) { 7823 f = parent; 7824 parent = tmp; 7825 } 7826 codeRoot = f; 7827 Slog.w(TAG, "Unrecognized code path " 7828 + codePath + " - using " + codeRoot); 7829 } catch (IOException e) { 7830 // Can't canonicalize the code path -- shenanigans? 7831 Slog.w(TAG, "Can't canonicalize code path " + codePath); 7832 return Environment.getRootDirectory().getPath(); 7833 } 7834 } 7835 return codeRoot.getPath(); 7836 } 7837 7838 /** 7839 * Derive and set the location of native libraries for the given package, 7840 * which varies depending on where and how the package was installed. 7841 */ setNativeLibraryPaths(PackageParser.Package pkg)7842 private void setNativeLibraryPaths(PackageParser.Package pkg) { 7843 final ApplicationInfo info = pkg.applicationInfo; 7844 final String codePath = pkg.codePath; 7845 final File codeFile = new File(codePath); 7846 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 7847 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 7848 7849 info.nativeLibraryRootDir = null; 7850 info.nativeLibraryRootRequiresIsa = false; 7851 info.nativeLibraryDir = null; 7852 info.secondaryNativeLibraryDir = null; 7853 7854 if (isApkFile(codeFile)) { 7855 // Monolithic install 7856 if (bundledApp) { 7857 // If "/system/lib64/apkname" exists, assume that is the per-package 7858 // native library directory to use; otherwise use "/system/lib/apkname". 7859 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 7860 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 7861 getPrimaryInstructionSet(info)); 7862 7863 // This is a bundled system app so choose the path based on the ABI. 7864 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 7865 // is just the default path. 7866 final String apkName = deriveCodePathName(codePath); 7867 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 7868 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 7869 apkName).getAbsolutePath(); 7870 7871 if (info.secondaryCpuAbi != null) { 7872 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 7873 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 7874 secondaryLibDir, apkName).getAbsolutePath(); 7875 } 7876 } else if (asecApp) { 7877 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 7878 .getAbsolutePath(); 7879 } else { 7880 final String apkName = deriveCodePathName(codePath); 7881 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 7882 .getAbsolutePath(); 7883 } 7884 7885 info.nativeLibraryRootRequiresIsa = false; 7886 info.nativeLibraryDir = info.nativeLibraryRootDir; 7887 } else { 7888 // Cluster install 7889 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 7890 info.nativeLibraryRootRequiresIsa = true; 7891 7892 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 7893 getPrimaryInstructionSet(info)).getAbsolutePath(); 7894 7895 if (info.secondaryCpuAbi != null) { 7896 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 7897 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 7898 } 7899 } 7900 } 7901 7902 /** 7903 * Calculate the abis and roots for a bundled app. These can uniquely 7904 * be determined from the contents of the system partition, i.e whether 7905 * it contains 64 or 32 bit shared libraries etc. We do not validate any 7906 * of this information, and instead assume that the system was built 7907 * sensibly. 7908 */ setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)7909 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 7910 PackageSetting pkgSetting) { 7911 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 7912 7913 // If "/system/lib64/apkname" exists, assume that is the per-package 7914 // native library directory to use; otherwise use "/system/lib/apkname". 7915 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 7916 setBundledAppAbi(pkg, apkRoot, apkName); 7917 // pkgSetting might be null during rescan following uninstall of updates 7918 // to a bundled app, so accommodate that possibility. The settings in 7919 // that case will be established later from the parsed package. 7920 // 7921 // If the settings aren't null, sync them up with what we've just derived. 7922 // note that apkRoot isn't stored in the package settings. 7923 if (pkgSetting != null) { 7924 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7925 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7926 } 7927 } 7928 7929 /** 7930 * Deduces the ABI of a bundled app and sets the relevant fields on the 7931 * parsed pkg object. 7932 * 7933 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 7934 * under which system libraries are installed. 7935 * @param apkName the name of the installed package. 7936 */ setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName)7937 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 7938 final File codeFile = new File(pkg.codePath); 7939 7940 final boolean has64BitLibs; 7941 final boolean has32BitLibs; 7942 if (isApkFile(codeFile)) { 7943 // Monolithic install 7944 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 7945 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 7946 } else { 7947 // Cluster install 7948 final File rootDir = new File(codeFile, LIB_DIR_NAME); 7949 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 7950 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 7951 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 7952 has64BitLibs = (new File(rootDir, isa)).exists(); 7953 } else { 7954 has64BitLibs = false; 7955 } 7956 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 7957 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 7958 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 7959 has32BitLibs = (new File(rootDir, isa)).exists(); 7960 } else { 7961 has32BitLibs = false; 7962 } 7963 } 7964 7965 if (has64BitLibs && !has32BitLibs) { 7966 // The package has 64 bit libs, but not 32 bit libs. Its primary 7967 // ABI should be 64 bit. We can safely assume here that the bundled 7968 // native libraries correspond to the most preferred ABI in the list. 7969 7970 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7971 pkg.applicationInfo.secondaryCpuAbi = null; 7972 } else if (has32BitLibs && !has64BitLibs) { 7973 // The package has 32 bit libs but not 64 bit libs. Its primary 7974 // ABI should be 32 bit. 7975 7976 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7977 pkg.applicationInfo.secondaryCpuAbi = null; 7978 } else if (has32BitLibs && has64BitLibs) { 7979 // The application has both 64 and 32 bit bundled libraries. We check 7980 // here that the app declares multiArch support, and warn if it doesn't. 7981 // 7982 // We will be lenient here and record both ABIs. The primary will be the 7983 // ABI that's higher on the list, i.e, a device that's configured to prefer 7984 // 64 bit apps will see a 64 bit primary ABI, 7985 7986 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 7987 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 7988 } 7989 7990 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 7991 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7992 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7993 } else { 7994 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7995 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7996 } 7997 } else { 7998 pkg.applicationInfo.primaryCpuAbi = null; 7999 pkg.applicationInfo.secondaryCpuAbi = null; 8000 } 8001 } 8002 killApplication(String pkgName, int appId, String reason)8003 private void killApplication(String pkgName, int appId, String reason) { 8004 // Request the ActivityManager to kill the process(only for existing packages) 8005 // so that we do not end up in a confused state while the user is still using the older 8006 // version of the application while the new one gets installed. 8007 IActivityManager am = ActivityManagerNative.getDefault(); 8008 if (am != null) { 8009 try { 8010 am.killApplicationWithAppId(pkgName, appId, reason); 8011 } catch (RemoteException e) { 8012 } 8013 } 8014 } 8015 removePackageLI(PackageSetting ps, boolean chatty)8016 void removePackageLI(PackageSetting ps, boolean chatty) { 8017 if (DEBUG_INSTALL) { 8018 if (chatty) 8019 Log.d(TAG, "Removing package " + ps.name); 8020 } 8021 8022 // writer 8023 synchronized (mPackages) { 8024 mPackages.remove(ps.name); 8025 final PackageParser.Package pkg = ps.pkg; 8026 if (pkg != null) { 8027 cleanPackageDataStructuresLILPw(pkg, chatty); 8028 } 8029 } 8030 } 8031 removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)8032 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8033 if (DEBUG_INSTALL) { 8034 if (chatty) 8035 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8036 } 8037 8038 // writer 8039 synchronized (mPackages) { 8040 mPackages.remove(pkg.applicationInfo.packageName); 8041 cleanPackageDataStructuresLILPw(pkg, chatty); 8042 } 8043 } 8044 cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)8045 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8046 int N = pkg.providers.size(); 8047 StringBuilder r = null; 8048 int i; 8049 for (i=0; i<N; i++) { 8050 PackageParser.Provider p = pkg.providers.get(i); 8051 mProviders.removeProvider(p); 8052 if (p.info.authority == null) { 8053 8054 /* There was another ContentProvider with this authority when 8055 * this app was installed so this authority is null, 8056 * Ignore it as we don't have to unregister the provider. 8057 */ 8058 continue; 8059 } 8060 String names[] = p.info.authority.split(";"); 8061 for (int j = 0; j < names.length; j++) { 8062 if (mProvidersByAuthority.get(names[j]) == p) { 8063 mProvidersByAuthority.remove(names[j]); 8064 if (DEBUG_REMOVE) { 8065 if (chatty) 8066 Log.d(TAG, "Unregistered content provider: " + names[j] 8067 + ", className = " + p.info.name + ", isSyncable = " 8068 + p.info.isSyncable); 8069 } 8070 } 8071 } 8072 if (DEBUG_REMOVE && chatty) { 8073 if (r == null) { 8074 r = new StringBuilder(256); 8075 } else { 8076 r.append(' '); 8077 } 8078 r.append(p.info.name); 8079 } 8080 } 8081 if (r != null) { 8082 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 8083 } 8084 8085 N = pkg.services.size(); 8086 r = null; 8087 for (i=0; i<N; i++) { 8088 PackageParser.Service s = pkg.services.get(i); 8089 mServices.removeService(s); 8090 if (chatty) { 8091 if (r == null) { 8092 r = new StringBuilder(256); 8093 } else { 8094 r.append(' '); 8095 } 8096 r.append(s.info.name); 8097 } 8098 } 8099 if (r != null) { 8100 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 8101 } 8102 8103 N = pkg.receivers.size(); 8104 r = null; 8105 for (i=0; i<N; i++) { 8106 PackageParser.Activity a = pkg.receivers.get(i); 8107 mReceivers.removeActivity(a, "receiver"); 8108 if (DEBUG_REMOVE && chatty) { 8109 if (r == null) { 8110 r = new StringBuilder(256); 8111 } else { 8112 r.append(' '); 8113 } 8114 r.append(a.info.name); 8115 } 8116 } 8117 if (r != null) { 8118 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 8119 } 8120 8121 N = pkg.activities.size(); 8122 r = null; 8123 for (i=0; i<N; i++) { 8124 PackageParser.Activity a = pkg.activities.get(i); 8125 mActivities.removeActivity(a, "activity"); 8126 if (DEBUG_REMOVE && chatty) { 8127 if (r == null) { 8128 r = new StringBuilder(256); 8129 } else { 8130 r.append(' '); 8131 } 8132 r.append(a.info.name); 8133 } 8134 } 8135 if (r != null) { 8136 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 8137 } 8138 8139 N = pkg.permissions.size(); 8140 r = null; 8141 for (i=0; i<N; i++) { 8142 PackageParser.Permission p = pkg.permissions.get(i); 8143 BasePermission bp = mSettings.mPermissions.get(p.info.name); 8144 if (bp == null) { 8145 bp = mSettings.mPermissionTrees.get(p.info.name); 8146 } 8147 if (bp != null && bp.perm == p) { 8148 bp.perm = null; 8149 if (DEBUG_REMOVE && chatty) { 8150 if (r == null) { 8151 r = new StringBuilder(256); 8152 } else { 8153 r.append(' '); 8154 } 8155 r.append(p.info.name); 8156 } 8157 } 8158 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8159 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 8160 if (appOpPerms != null) { 8161 appOpPerms.remove(pkg.packageName); 8162 } 8163 } 8164 } 8165 if (r != null) { 8166 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8167 } 8168 8169 N = pkg.requestedPermissions.size(); 8170 r = null; 8171 for (i=0; i<N; i++) { 8172 String perm = pkg.requestedPermissions.get(i); 8173 BasePermission bp = mSettings.mPermissions.get(perm); 8174 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8175 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 8176 if (appOpPerms != null) { 8177 appOpPerms.remove(pkg.packageName); 8178 if (appOpPerms.isEmpty()) { 8179 mAppOpPermissionPackages.remove(perm); 8180 } 8181 } 8182 } 8183 } 8184 if (r != null) { 8185 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8186 } 8187 8188 N = pkg.instrumentation.size(); 8189 r = null; 8190 for (i=0; i<N; i++) { 8191 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8192 mInstrumentation.remove(a.getComponentName()); 8193 if (DEBUG_REMOVE && chatty) { 8194 if (r == null) { 8195 r = new StringBuilder(256); 8196 } else { 8197 r.append(' '); 8198 } 8199 r.append(a.info.name); 8200 } 8201 } 8202 if (r != null) { 8203 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 8204 } 8205 8206 r = null; 8207 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8208 // Only system apps can hold shared libraries. 8209 if (pkg.libraryNames != null) { 8210 for (i=0; i<pkg.libraryNames.size(); i++) { 8211 String name = pkg.libraryNames.get(i); 8212 SharedLibraryEntry cur = mSharedLibraries.get(name); 8213 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 8214 mSharedLibraries.remove(name); 8215 if (DEBUG_REMOVE && chatty) { 8216 if (r == null) { 8217 r = new StringBuilder(256); 8218 } else { 8219 r.append(' '); 8220 } 8221 r.append(name); 8222 } 8223 } 8224 } 8225 } 8226 } 8227 if (r != null) { 8228 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 8229 } 8230 } 8231 hasPermission(PackageParser.Package pkgInfo, String perm)8232 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 8233 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 8234 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 8235 return true; 8236 } 8237 } 8238 return false; 8239 } 8240 8241 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 8242 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 8243 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 8244 updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)8245 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 8246 int flags) { 8247 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 8248 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 8249 } 8250 updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags)8251 private void updatePermissionsLPw(String changingPkg, 8252 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 8253 // Make sure there are no dangling permission trees. 8254 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 8255 while (it.hasNext()) { 8256 final BasePermission bp = it.next(); 8257 if (bp.packageSetting == null) { 8258 // We may not yet have parsed the package, so just see if 8259 // we still know about its settings. 8260 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 8261 } 8262 if (bp.packageSetting == null) { 8263 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 8264 + " from package " + bp.sourcePackage); 8265 it.remove(); 8266 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 8267 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 8268 Slog.i(TAG, "Removing old permission tree: " + bp.name 8269 + " from package " + bp.sourcePackage); 8270 flags |= UPDATE_PERMISSIONS_ALL; 8271 it.remove(); 8272 } 8273 } 8274 } 8275 8276 // Make sure all dynamic permissions have been assigned to a package, 8277 // and make sure there are no dangling permissions. 8278 it = mSettings.mPermissions.values().iterator(); 8279 while (it.hasNext()) { 8280 final BasePermission bp = it.next(); 8281 if (bp.type == BasePermission.TYPE_DYNAMIC) { 8282 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 8283 + bp.name + " pkg=" + bp.sourcePackage 8284 + " info=" + bp.pendingInfo); 8285 if (bp.packageSetting == null && bp.pendingInfo != null) { 8286 final BasePermission tree = findPermissionTreeLP(bp.name); 8287 if (tree != null && tree.perm != null) { 8288 bp.packageSetting = tree.packageSetting; 8289 bp.perm = new PackageParser.Permission(tree.perm.owner, 8290 new PermissionInfo(bp.pendingInfo)); 8291 bp.perm.info.packageName = tree.perm.info.packageName; 8292 bp.perm.info.name = bp.name; 8293 bp.uid = tree.uid; 8294 } 8295 } 8296 } 8297 if (bp.packageSetting == null) { 8298 // We may not yet have parsed the package, so just see if 8299 // we still know about its settings. 8300 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 8301 } 8302 if (bp.packageSetting == null) { 8303 Slog.w(TAG, "Removing dangling permission: " + bp.name 8304 + " from package " + bp.sourcePackage); 8305 it.remove(); 8306 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 8307 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 8308 Slog.i(TAG, "Removing old permission: " + bp.name 8309 + " from package " + bp.sourcePackage); 8310 flags |= UPDATE_PERMISSIONS_ALL; 8311 it.remove(); 8312 } 8313 } 8314 } 8315 8316 // Now update the permissions for all packages, in particular 8317 // replace the granted permissions of the system packages. 8318 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 8319 for (PackageParser.Package pkg : mPackages.values()) { 8320 if (pkg != pkgInfo) { 8321 // Only replace for packages on requested volume 8322 final String volumeUuid = getVolumeUuidForPackage(pkg); 8323 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 8324 && Objects.equals(replaceVolumeUuid, volumeUuid); 8325 grantPermissionsLPw(pkg, replace, changingPkg); 8326 } 8327 } 8328 } 8329 8330 if (pkgInfo != null) { 8331 // Only replace for packages on requested volume 8332 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 8333 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 8334 && Objects.equals(replaceVolumeUuid, volumeUuid); 8335 grantPermissionsLPw(pkgInfo, replace, changingPkg); 8336 } 8337 } 8338 grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)8339 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 8340 String packageOfInterest) { 8341 // IMPORTANT: There are two types of permissions: install and runtime. 8342 // Install time permissions are granted when the app is installed to 8343 // all device users and users added in the future. Runtime permissions 8344 // are granted at runtime explicitly to specific users. Normal and signature 8345 // protected permissions are install time permissions. Dangerous permissions 8346 // are install permissions if the app's target SDK is Lollipop MR1 or older, 8347 // otherwise they are runtime permissions. This function does not manage 8348 // runtime permissions except for the case an app targeting Lollipop MR1 8349 // being upgraded to target a newer SDK, in which case dangerous permissions 8350 // are transformed from install time to runtime ones. 8351 8352 final PackageSetting ps = (PackageSetting) pkg.mExtras; 8353 if (ps == null) { 8354 return; 8355 } 8356 8357 PermissionsState permissionsState = ps.getPermissionsState(); 8358 PermissionsState origPermissions = permissionsState; 8359 8360 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 8361 8362 boolean runtimePermissionsRevoked = false; 8363 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 8364 8365 boolean changedInstallPermission = false; 8366 8367 if (replace) { 8368 ps.installPermissionsFixed = false; 8369 if (!ps.isSharedUser()) { 8370 origPermissions = new PermissionsState(permissionsState); 8371 permissionsState.reset(); 8372 } else { 8373 // We need to know only about runtime permission changes since the 8374 // calling code always writes the install permissions state but 8375 // the runtime ones are written only if changed. The only cases of 8376 // changed runtime permissions here are promotion of an install to 8377 // runtime and revocation of a runtime from a shared user. 8378 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 8379 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 8380 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 8381 runtimePermissionsRevoked = true; 8382 } 8383 } 8384 } 8385 8386 permissionsState.setGlobalGids(mGlobalGids); 8387 8388 final int N = pkg.requestedPermissions.size(); 8389 for (int i=0; i<N; i++) { 8390 final String name = pkg.requestedPermissions.get(i); 8391 final BasePermission bp = mSettings.mPermissions.get(name); 8392 8393 if (DEBUG_INSTALL) { 8394 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 8395 } 8396 8397 if (bp == null || bp.packageSetting == null) { 8398 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 8399 Slog.w(TAG, "Unknown permission " + name 8400 + " in package " + pkg.packageName); 8401 } 8402 continue; 8403 } 8404 8405 final String perm = bp.name; 8406 boolean allowedSig = false; 8407 int grant = GRANT_DENIED; 8408 8409 // Keep track of app op permissions. 8410 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8411 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 8412 if (pkgs == null) { 8413 pkgs = new ArraySet<>(); 8414 mAppOpPermissionPackages.put(bp.name, pkgs); 8415 } 8416 pkgs.add(pkg.packageName); 8417 } 8418 8419 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 8420 switch (level) { 8421 case PermissionInfo.PROTECTION_NORMAL: { 8422 // For all apps normal permissions are install time ones. 8423 grant = GRANT_INSTALL; 8424 } break; 8425 8426 case PermissionInfo.PROTECTION_DANGEROUS: { 8427 if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) { 8428 // For legacy apps dangerous permissions are install time ones. 8429 grant = GRANT_INSTALL_LEGACY; 8430 } else if (origPermissions.hasInstallPermission(bp.name)) { 8431 // For legacy apps that became modern, install becomes runtime. 8432 grant = GRANT_UPGRADE; 8433 } else if (mPromoteSystemApps 8434 && isSystemApp(ps) 8435 && mExistingSystemPackages.contains(ps.name)) { 8436 // For legacy system apps, install becomes runtime. 8437 // We cannot check hasInstallPermission() for system apps since those 8438 // permissions were granted implicitly and not persisted pre-M. 8439 grant = GRANT_UPGRADE; 8440 } else { 8441 // For modern apps keep runtime permissions unchanged. 8442 grant = GRANT_RUNTIME; 8443 } 8444 } break; 8445 8446 case PermissionInfo.PROTECTION_SIGNATURE: { 8447 // For all apps signature permissions are install time ones. 8448 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 8449 if (allowedSig) { 8450 grant = GRANT_INSTALL; 8451 } 8452 } break; 8453 } 8454 8455 if (DEBUG_INSTALL) { 8456 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 8457 } 8458 8459 if (grant != GRANT_DENIED) { 8460 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 8461 // If this is an existing, non-system package, then 8462 // we can't add any new permissions to it. 8463 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 8464 // Except... if this is a permission that was added 8465 // to the platform (note: need to only do this when 8466 // updating the platform). 8467 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 8468 grant = GRANT_DENIED; 8469 } 8470 } 8471 } 8472 8473 switch (grant) { 8474 case GRANT_INSTALL: { 8475 // Revoke this as runtime permission to handle the case of 8476 // a runtime permission being downgraded to an install one. 8477 for (int userId : UserManagerService.getInstance().getUserIds()) { 8478 if (origPermissions.getRuntimePermissionState( 8479 bp.name, userId) != null) { 8480 // Revoke the runtime permission and clear the flags. 8481 origPermissions.revokeRuntimePermission(bp, userId); 8482 origPermissions.updatePermissionFlags(bp, userId, 8483 PackageManager.MASK_PERMISSION_FLAGS, 0); 8484 // If we revoked a permission permission, we have to write. 8485 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8486 changedRuntimePermissionUserIds, userId); 8487 } 8488 } 8489 // Grant an install permission. 8490 if (permissionsState.grantInstallPermission(bp) != 8491 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8492 changedInstallPermission = true; 8493 } 8494 } break; 8495 8496 case GRANT_INSTALL_LEGACY: { 8497 // Grant an install permission. 8498 if (permissionsState.grantInstallPermission(bp) != 8499 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8500 changedInstallPermission = true; 8501 } 8502 } break; 8503 8504 case GRANT_RUNTIME: { 8505 // Grant previously granted runtime permissions. 8506 for (int userId : UserManagerService.getInstance().getUserIds()) { 8507 PermissionState permissionState = origPermissions 8508 .getRuntimePermissionState(bp.name, userId); 8509 final int flags = permissionState != null 8510 ? permissionState.getFlags() : 0; 8511 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 8512 if (permissionsState.grantRuntimePermission(bp, userId) == 8513 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8514 // If we cannot put the permission as it was, we have to write. 8515 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8516 changedRuntimePermissionUserIds, userId); 8517 } 8518 } 8519 // Propagate the permission flags. 8520 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 8521 } 8522 } break; 8523 8524 case GRANT_UPGRADE: { 8525 // Grant runtime permissions for a previously held install permission. 8526 PermissionState permissionState = origPermissions 8527 .getInstallPermissionState(bp.name); 8528 final int flags = permissionState != null ? permissionState.getFlags() : 0; 8529 8530 if (origPermissions.revokeInstallPermission(bp) 8531 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 8532 // We will be transferring the permission flags, so clear them. 8533 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 8534 PackageManager.MASK_PERMISSION_FLAGS, 0); 8535 changedInstallPermission = true; 8536 } 8537 8538 // If the permission is not to be promoted to runtime we ignore it and 8539 // also its other flags as they are not applicable to install permissions. 8540 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 8541 for (int userId : currentUserIds) { 8542 if (permissionsState.grantRuntimePermission(bp, userId) != 8543 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8544 // Transfer the permission flags. 8545 permissionsState.updatePermissionFlags(bp, userId, 8546 flags, flags); 8547 // If we granted the permission, we have to write. 8548 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 8549 changedRuntimePermissionUserIds, userId); 8550 } 8551 } 8552 } 8553 } break; 8554 8555 default: { 8556 if (packageOfInterest == null 8557 || packageOfInterest.equals(pkg.packageName)) { 8558 Slog.w(TAG, "Not granting permission " + perm 8559 + " to package " + pkg.packageName 8560 + " because it was previously installed without"); 8561 } 8562 } break; 8563 } 8564 } else { 8565 if (permissionsState.revokeInstallPermission(bp) != 8566 PermissionsState.PERMISSION_OPERATION_FAILURE) { 8567 // Also drop the permission flags. 8568 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 8569 PackageManager.MASK_PERMISSION_FLAGS, 0); 8570 changedInstallPermission = true; 8571 Slog.i(TAG, "Un-granting permission " + perm 8572 + " from package " + pkg.packageName 8573 + " (protectionLevel=" + bp.protectionLevel 8574 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 8575 + ")"); 8576 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 8577 // Don't print warning for app op permissions, since it is fine for them 8578 // not to be granted, there is a UI for the user to decide. 8579 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 8580 Slog.w(TAG, "Not granting permission " + perm 8581 + " to package " + pkg.packageName 8582 + " (protectionLevel=" + bp.protectionLevel 8583 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 8584 + ")"); 8585 } 8586 } 8587 } 8588 } 8589 8590 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 8591 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 8592 // This is the first that we have heard about this package, so the 8593 // permissions we have now selected are fixed until explicitly 8594 // changed. 8595 ps.installPermissionsFixed = true; 8596 } 8597 8598 // Persist the runtime permissions state for users with changes. If permissions 8599 // were revoked because no app in the shared user declares them we have to 8600 // write synchronously to avoid losing runtime permissions state. 8601 for (int userId : changedRuntimePermissionUserIds) { 8602 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 8603 } 8604 } 8605 isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)8606 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 8607 boolean allowed = false; 8608 final int NP = PackageParser.NEW_PERMISSIONS.length; 8609 for (int ip=0; ip<NP; ip++) { 8610 final PackageParser.NewPermissionInfo npi 8611 = PackageParser.NEW_PERMISSIONS[ip]; 8612 if (npi.name.equals(perm) 8613 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 8614 allowed = true; 8615 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 8616 + pkg.packageName); 8617 break; 8618 } 8619 } 8620 return allowed; 8621 } 8622 grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions)8623 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 8624 BasePermission bp, PermissionsState origPermissions) { 8625 boolean allowed; 8626 allowed = (compareSignatures( 8627 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 8628 == PackageManager.SIGNATURE_MATCH) 8629 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 8630 == PackageManager.SIGNATURE_MATCH); 8631 if (!allowed && (bp.protectionLevel 8632 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 8633 if (isSystemApp(pkg)) { 8634 // For updated system applications, a system permission 8635 // is granted only if it had been defined by the original application. 8636 if (pkg.isUpdatedSystemApp()) { 8637 final PackageSetting sysPs = mSettings 8638 .getDisabledSystemPkgLPr(pkg.packageName); 8639 if (sysPs.getPermissionsState().hasInstallPermission(perm)) { 8640 // If the original was granted this permission, we take 8641 // that grant decision as read and propagate it to the 8642 // update. 8643 if (sysPs.isPrivileged()) { 8644 allowed = true; 8645 } 8646 } else { 8647 // The system apk may have been updated with an older 8648 // version of the one on the data partition, but which 8649 // granted a new system permission that it didn't have 8650 // before. In this case we do want to allow the app to 8651 // now get the new permission if the ancestral apk is 8652 // privileged to get it. 8653 if (sysPs.pkg != null && sysPs.isPrivileged()) { 8654 for (int j=0; 8655 j<sysPs.pkg.requestedPermissions.size(); j++) { 8656 if (perm.equals( 8657 sysPs.pkg.requestedPermissions.get(j))) { 8658 allowed = true; 8659 break; 8660 } 8661 } 8662 } 8663 } 8664 } else { 8665 allowed = isPrivilegedApp(pkg); 8666 } 8667 } 8668 } 8669 if (!allowed) { 8670 if (!allowed && (bp.protectionLevel 8671 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 8672 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 8673 // If this was a previously normal/dangerous permission that got moved 8674 // to a system permission as part of the runtime permission redesign, then 8675 // we still want to blindly grant it to old apps. 8676 allowed = true; 8677 } 8678 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 8679 && pkg.packageName.equals(mRequiredInstallerPackage)) { 8680 // If this permission is to be granted to the system installer and 8681 // this app is an installer, then it gets the permission. 8682 allowed = true; 8683 } 8684 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 8685 && pkg.packageName.equals(mRequiredVerifierPackage)) { 8686 // If this permission is to be granted to the system verifier and 8687 // this app is a verifier, then it gets the permission. 8688 allowed = true; 8689 } 8690 if (!allowed && (bp.protectionLevel 8691 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 8692 && isSystemApp(pkg)) { 8693 // Any pre-installed system app is allowed to get this permission. 8694 allowed = true; 8695 } 8696 if (!allowed && (bp.protectionLevel 8697 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 8698 // For development permissions, a development permission 8699 // is granted only if it was already granted. 8700 allowed = origPermissions.hasInstallPermission(perm); 8701 } 8702 } 8703 return allowed; 8704 } 8705 8706 final class ActivityIntentResolver 8707 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)8708 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8709 boolean defaultOnly, int userId) { 8710 if (!sUserManager.exists(userId)) return null; 8711 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8712 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8713 } 8714 queryIntent(Intent intent, String resolvedType, int flags, int userId)8715 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8716 int userId) { 8717 if (!sUserManager.exists(userId)) return null; 8718 mFlags = flags; 8719 return super.queryIntent(intent, resolvedType, 8720 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8721 } 8722 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)8723 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8724 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 8725 if (!sUserManager.exists(userId)) return null; 8726 if (packageActivities == null) { 8727 return null; 8728 } 8729 mFlags = flags; 8730 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8731 final int N = packageActivities.size(); 8732 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 8733 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 8734 8735 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 8736 for (int i = 0; i < N; ++i) { 8737 intentFilters = packageActivities.get(i).intents; 8738 if (intentFilters != null && intentFilters.size() > 0) { 8739 PackageParser.ActivityIntentInfo[] array = 8740 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 8741 intentFilters.toArray(array); 8742 listCut.add(array); 8743 } 8744 } 8745 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8746 } 8747 8748 /** 8749 * Finds a privileged activity that matches the specified activity names. 8750 */ findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo)8751 private PackageParser.Activity findMatchingActivity( 8752 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 8753 for (PackageParser.Activity sysActivity : activityList) { 8754 if (sysActivity.info.name.equals(activityInfo.name)) { 8755 return sysActivity; 8756 } 8757 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 8758 return sysActivity; 8759 } 8760 if (sysActivity.info.targetActivity != null) { 8761 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 8762 return sysActivity; 8763 } 8764 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 8765 return sysActivity; 8766 } 8767 } 8768 } 8769 return null; 8770 } 8771 8772 public class IterGenerator<E> { generate(ActivityIntentInfo info)8773 public Iterator<E> generate(ActivityIntentInfo info) { 8774 return null; 8775 } 8776 } 8777 8778 public class ActionIterGenerator extends IterGenerator<String> { 8779 @Override generate(ActivityIntentInfo info)8780 public Iterator<String> generate(ActivityIntentInfo info) { 8781 return info.actionsIterator(); 8782 } 8783 } 8784 8785 public class CategoriesIterGenerator extends IterGenerator<String> { 8786 @Override generate(ActivityIntentInfo info)8787 public Iterator<String> generate(ActivityIntentInfo info) { 8788 return info.categoriesIterator(); 8789 } 8790 } 8791 8792 public class SchemesIterGenerator extends IterGenerator<String> { 8793 @Override generate(ActivityIntentInfo info)8794 public Iterator<String> generate(ActivityIntentInfo info) { 8795 return info.schemesIterator(); 8796 } 8797 } 8798 8799 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 8800 @Override generate(ActivityIntentInfo info)8801 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 8802 return info.authoritiesIterator(); 8803 } 8804 } 8805 8806 /** 8807 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 8808 * MODIFIED. Do not pass in a list that should not be changed. 8809 */ getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator)8810 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 8811 IterGenerator<T> generator, Iterator<T> searchIterator) { 8812 // loop through the set of actions; every one must be found in the intent filter 8813 while (searchIterator.hasNext()) { 8814 // we must have at least one filter in the list to consider a match 8815 if (intentList.size() == 0) { 8816 break; 8817 } 8818 8819 final T searchAction = searchIterator.next(); 8820 8821 // loop through the set of intent filters 8822 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 8823 while (intentIter.hasNext()) { 8824 final ActivityIntentInfo intentInfo = intentIter.next(); 8825 boolean selectionFound = false; 8826 8827 // loop through the intent filter's selection criteria; at least one 8828 // of them must match the searched criteria 8829 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 8830 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 8831 final T intentSelection = intentSelectionIter.next(); 8832 if (intentSelection != null && intentSelection.equals(searchAction)) { 8833 selectionFound = true; 8834 break; 8835 } 8836 } 8837 8838 // the selection criteria wasn't found in this filter's set; this filter 8839 // is not a potential match 8840 if (!selectionFound) { 8841 intentIter.remove(); 8842 } 8843 } 8844 } 8845 } 8846 8847 /** 8848 * Adjusts the priority of the given intent filter according to policy. 8849 * <p> 8850 * <ul> 8851 * <li>The priority for unbundled updates to system applications is capped to the 8852 * priority defined on the system partition</li> 8853 * </ul> 8854 */ adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent)8855 private void adjustPriority( 8856 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 8857 // nothing to do; priority is fine as-is 8858 if (intent.getPriority() <= 0) { 8859 return; 8860 } 8861 8862 final ActivityInfo activityInfo = intent.activity.info; 8863 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 8864 8865 final boolean systemApp = applicationInfo.isSystemApp(); 8866 if (!systemApp) { 8867 // non-system applications can never define a priority >0 8868 Slog.w(TAG, "Non-system app; cap priority to 0;" 8869 + " package: " + applicationInfo.packageName 8870 + " activity: " + intent.activity.className 8871 + " origPrio: " + intent.getPriority()); 8872 intent.setPriority(0); 8873 return; 8874 } 8875 8876 if (systemActivities == null) { 8877 // the system package is not disabled; we're parsing the system partition 8878 // apps on the system image get whatever priority they request 8879 return; 8880 } 8881 8882 // system app unbundled update ... try to find the same activity 8883 final PackageParser.Activity foundActivity = 8884 findMatchingActivity(systemActivities, activityInfo); 8885 if (foundActivity == null) { 8886 // this is a new activity; it cannot obtain >0 priority 8887 if (DEBUG_FILTERS) { 8888 Slog.i(TAG, "New activity; cap priority to 0;" 8889 + " package: " + applicationInfo.packageName 8890 + " activity: " + intent.activity.className 8891 + " origPrio: " + intent.getPriority()); 8892 } 8893 intent.setPriority(0); 8894 return; 8895 } 8896 8897 // found activity, now check for filter equivalence 8898 8899 // a shallow copy is enough; we modify the list, not its contents 8900 final List<ActivityIntentInfo> intentListCopy = 8901 new ArrayList<>(foundActivity.intents); 8902 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 8903 8904 // find matching action subsets 8905 final Iterator<String> actionsIterator = intent.actionsIterator(); 8906 if (actionsIterator != null) { 8907 getIntentListSubset( 8908 intentListCopy, new ActionIterGenerator(), actionsIterator); 8909 if (intentListCopy.size() == 0) { 8910 // no more intents to match; we're not equivalent 8911 if (DEBUG_FILTERS) { 8912 Slog.i(TAG, "Mismatched action; cap priority to 0;" 8913 + " package: " + applicationInfo.packageName 8914 + " activity: " + intent.activity.className 8915 + " origPrio: " + intent.getPriority()); 8916 } 8917 intent.setPriority(0); 8918 return; 8919 } 8920 } 8921 8922 // find matching category subsets 8923 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 8924 if (categoriesIterator != null) { 8925 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 8926 categoriesIterator); 8927 if (intentListCopy.size() == 0) { 8928 // no more intents to match; we're not equivalent 8929 if (DEBUG_FILTERS) { 8930 Slog.i(TAG, "Mismatched category; cap priority to 0;" 8931 + " package: " + applicationInfo.packageName 8932 + " activity: " + intent.activity.className 8933 + " origPrio: " + intent.getPriority()); 8934 } 8935 intent.setPriority(0); 8936 return; 8937 } 8938 } 8939 8940 // find matching schemes subsets 8941 final Iterator<String> schemesIterator = intent.schemesIterator(); 8942 if (schemesIterator != null) { 8943 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 8944 schemesIterator); 8945 if (intentListCopy.size() == 0) { 8946 // no more intents to match; we're not equivalent 8947 if (DEBUG_FILTERS) { 8948 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 8949 + " package: " + applicationInfo.packageName 8950 + " activity: " + intent.activity.className 8951 + " origPrio: " + intent.getPriority()); 8952 } 8953 intent.setPriority(0); 8954 return; 8955 } 8956 } 8957 8958 // find matching authorities subsets 8959 final Iterator<IntentFilter.AuthorityEntry> 8960 authoritiesIterator = intent.authoritiesIterator(); 8961 if (authoritiesIterator != null) { 8962 getIntentListSubset(intentListCopy, 8963 new AuthoritiesIterGenerator(), 8964 authoritiesIterator); 8965 if (intentListCopy.size() == 0) { 8966 // no more intents to match; we're not equivalent 8967 if (DEBUG_FILTERS) { 8968 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 8969 + " package: " + applicationInfo.packageName 8970 + " activity: " + intent.activity.className 8971 + " origPrio: " + intent.getPriority()); 8972 } 8973 intent.setPriority(0); 8974 return; 8975 } 8976 } 8977 8978 // we found matching filter(s); app gets the max priority of all intents 8979 int cappedPriority = 0; 8980 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 8981 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 8982 } 8983 if (intent.getPriority() > cappedPriority) { 8984 if (DEBUG_FILTERS) { 8985 Slog.i(TAG, "Found matching filter(s);" 8986 + " cap priority to " + cappedPriority + ";" 8987 + " package: " + applicationInfo.packageName 8988 + " activity: " + intent.activity.className 8989 + " origPrio: " + intent.getPriority()); 8990 } 8991 intent.setPriority(cappedPriority); 8992 return; 8993 } 8994 // all this for nothing; the requested priority was <= what was on the system 8995 } 8996 addActivity(PackageParser.Activity a, String type)8997 public final void addActivity(PackageParser.Activity a, String type) { 8998 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 8999 mActivities.put(a.getComponentName(), a); 9000 if (DEBUG_SHOW_INFO) 9001 Log.v( 9002 TAG, " " + type + " " + 9003 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 9004 if (DEBUG_SHOW_INFO) 9005 Log.v(TAG, " Class=" + a.info.name); 9006 final int NI = a.intents.size(); 9007 for (int j=0; j<NI; j++) { 9008 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9009 if ("activity".equals(type)) { 9010 final PackageSetting ps = 9011 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 9012 final List<PackageParser.Activity> systemActivities = 9013 ps != null && ps.pkg != null ? ps.pkg.activities : null; 9014 adjustPriority(systemActivities, intent); 9015 } 9016 if (DEBUG_SHOW_INFO) { 9017 Log.v(TAG, " IntentFilter:"); 9018 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9019 } 9020 if (!intent.debugCheck()) { 9021 Log.w(TAG, "==> For Activity " + a.info.name); 9022 } 9023 addFilter(intent); 9024 } 9025 } 9026 removeActivity(PackageParser.Activity a, String type)9027 public final void removeActivity(PackageParser.Activity a, String type) { 9028 mActivities.remove(a.getComponentName()); 9029 if (DEBUG_SHOW_INFO) { 9030 Log.v(TAG, " " + type + " " 9031 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 9032 : a.info.name) + ":"); 9033 Log.v(TAG, " Class=" + a.info.name); 9034 } 9035 final int NI = a.intents.size(); 9036 for (int j=0; j<NI; j++) { 9037 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9038 if (DEBUG_SHOW_INFO) { 9039 Log.v(TAG, " IntentFilter:"); 9040 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9041 } 9042 removeFilter(intent); 9043 } 9044 } 9045 9046 @Override allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)9047 protected boolean allowFilterResult( 9048 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 9049 ActivityInfo filterAi = filter.activity.info; 9050 for (int i=dest.size()-1; i>=0; i--) { 9051 ActivityInfo destAi = dest.get(i).activityInfo; 9052 if (destAi.name == filterAi.name 9053 && destAi.packageName == filterAi.packageName) { 9054 return false; 9055 } 9056 } 9057 return true; 9058 } 9059 9060 @Override newArray(int size)9061 protected ActivityIntentInfo[] newArray(int size) { 9062 return new ActivityIntentInfo[size]; 9063 } 9064 9065 @Override isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)9066 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 9067 if (!sUserManager.exists(userId)) return true; 9068 PackageParser.Package p = filter.activity.owner; 9069 if (p != null) { 9070 PackageSetting ps = (PackageSetting)p.mExtras; 9071 if (ps != null) { 9072 // System apps are never considered stopped for purposes of 9073 // filtering, because there may be no way for the user to 9074 // actually re-launch them. 9075 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 9076 && ps.getStopped(userId); 9077 } 9078 } 9079 return false; 9080 } 9081 9082 @Override isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)9083 protected boolean isPackageForFilter(String packageName, 9084 PackageParser.ActivityIntentInfo info) { 9085 return packageName.equals(info.activity.owner.packageName); 9086 } 9087 9088 @Override newResult(PackageParser.ActivityIntentInfo info, int match, int userId)9089 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 9090 int match, int userId) { 9091 if (!sUserManager.exists(userId)) return null; 9092 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 9093 return null; 9094 } 9095 final PackageParser.Activity activity = info.activity; 9096 if (mSafeMode && (activity.info.applicationInfo.flags 9097 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9098 return null; 9099 } 9100 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 9101 if (ps == null) { 9102 return null; 9103 } 9104 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 9105 ps.readUserState(userId), userId); 9106 if (ai == null) { 9107 return null; 9108 } 9109 final ResolveInfo res = new ResolveInfo(); 9110 res.activityInfo = ai; 9111 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9112 res.filter = info; 9113 } 9114 if (info != null) { 9115 res.handleAllWebDataURI = info.handleAllWebDataURI(); 9116 } 9117 res.priority = info.getPriority(); 9118 res.preferredOrder = activity.owner.mPreferredOrder; 9119 //System.out.println("Result: " + res.activityInfo.className + 9120 // " = " + res.priority); 9121 res.match = match; 9122 res.isDefault = info.hasDefault; 9123 res.labelRes = info.labelRes; 9124 res.nonLocalizedLabel = info.nonLocalizedLabel; 9125 if (userNeedsBadging(userId)) { 9126 res.noResourceId = true; 9127 } else { 9128 res.icon = info.icon; 9129 } 9130 res.iconResourceId = info.icon; 9131 res.system = res.activityInfo.applicationInfo.isSystemApp(); 9132 return res; 9133 } 9134 9135 @Override sortResults(List<ResolveInfo> results)9136 protected void sortResults(List<ResolveInfo> results) { 9137 Collections.sort(results, mResolvePrioritySorter); 9138 } 9139 9140 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)9141 protected void dumpFilter(PrintWriter out, String prefix, 9142 PackageParser.ActivityIntentInfo filter) { 9143 out.print(prefix); out.print( 9144 Integer.toHexString(System.identityHashCode(filter.activity))); 9145 out.print(' '); 9146 filter.activity.printComponentShortName(out); 9147 out.print(" filter "); 9148 out.println(Integer.toHexString(System.identityHashCode(filter))); 9149 } 9150 9151 @Override filterToLabel(PackageParser.ActivityIntentInfo filter)9152 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 9153 return filter.activity; 9154 } 9155 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)9156 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9157 PackageParser.Activity activity = (PackageParser.Activity)label; 9158 out.print(prefix); out.print( 9159 Integer.toHexString(System.identityHashCode(activity))); 9160 out.print(' '); 9161 activity.printComponentShortName(out); 9162 if (count > 1) { 9163 out.print(" ("); out.print(count); out.print(" filters)"); 9164 } 9165 out.println(); 9166 } 9167 9168 // Keys are String (activity class name), values are Activity. 9169 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 9170 = new ArrayMap<ComponentName, PackageParser.Activity>(); 9171 private int mFlags; 9172 } 9173 9174 private final class ServiceIntentResolver 9175 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)9176 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9177 boolean defaultOnly, int userId) { 9178 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9179 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9180 } 9181 queryIntent(Intent intent, String resolvedType, int flags, int userId)9182 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9183 int userId) { 9184 if (!sUserManager.exists(userId)) return null; 9185 mFlags = flags; 9186 return super.queryIntent(intent, resolvedType, 9187 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9188 } 9189 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)9190 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9191 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 9192 if (!sUserManager.exists(userId)) return null; 9193 if (packageServices == null) { 9194 return null; 9195 } 9196 mFlags = flags; 9197 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9198 final int N = packageServices.size(); 9199 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 9200 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 9201 9202 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 9203 for (int i = 0; i < N; ++i) { 9204 intentFilters = packageServices.get(i).intents; 9205 if (intentFilters != null && intentFilters.size() > 0) { 9206 PackageParser.ServiceIntentInfo[] array = 9207 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 9208 intentFilters.toArray(array); 9209 listCut.add(array); 9210 } 9211 } 9212 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9213 } 9214 addService(PackageParser.Service s)9215 public final void addService(PackageParser.Service s) { 9216 mServices.put(s.getComponentName(), s); 9217 if (DEBUG_SHOW_INFO) { 9218 Log.v(TAG, " " 9219 + (s.info.nonLocalizedLabel != null 9220 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9221 Log.v(TAG, " Class=" + s.info.name); 9222 } 9223 final int NI = s.intents.size(); 9224 int j; 9225 for (j=0; j<NI; j++) { 9226 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9227 if (DEBUG_SHOW_INFO) { 9228 Log.v(TAG, " IntentFilter:"); 9229 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9230 } 9231 if (!intent.debugCheck()) { 9232 Log.w(TAG, "==> For Service " + s.info.name); 9233 } 9234 addFilter(intent); 9235 } 9236 } 9237 removeService(PackageParser.Service s)9238 public final void removeService(PackageParser.Service s) { 9239 mServices.remove(s.getComponentName()); 9240 if (DEBUG_SHOW_INFO) { 9241 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 9242 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9243 Log.v(TAG, " Class=" + s.info.name); 9244 } 9245 final int NI = s.intents.size(); 9246 int j; 9247 for (j=0; j<NI; j++) { 9248 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9249 if (DEBUG_SHOW_INFO) { 9250 Log.v(TAG, " IntentFilter:"); 9251 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9252 } 9253 removeFilter(intent); 9254 } 9255 } 9256 9257 @Override allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)9258 protected boolean allowFilterResult( 9259 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 9260 ServiceInfo filterSi = filter.service.info; 9261 for (int i=dest.size()-1; i>=0; i--) { 9262 ServiceInfo destAi = dest.get(i).serviceInfo; 9263 if (destAi.name == filterSi.name 9264 && destAi.packageName == filterSi.packageName) { 9265 return false; 9266 } 9267 } 9268 return true; 9269 } 9270 9271 @Override newArray(int size)9272 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 9273 return new PackageParser.ServiceIntentInfo[size]; 9274 } 9275 9276 @Override isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)9277 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 9278 if (!sUserManager.exists(userId)) return true; 9279 PackageParser.Package p = filter.service.owner; 9280 if (p != null) { 9281 PackageSetting ps = (PackageSetting)p.mExtras; 9282 if (ps != null) { 9283 // System apps are never considered stopped for purposes of 9284 // filtering, because there may be no way for the user to 9285 // actually re-launch them. 9286 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9287 && ps.getStopped(userId); 9288 } 9289 } 9290 return false; 9291 } 9292 9293 @Override isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)9294 protected boolean isPackageForFilter(String packageName, 9295 PackageParser.ServiceIntentInfo info) { 9296 return packageName.equals(info.service.owner.packageName); 9297 } 9298 9299 @Override newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)9300 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 9301 int match, int userId) { 9302 if (!sUserManager.exists(userId)) return null; 9303 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 9304 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 9305 return null; 9306 } 9307 final PackageParser.Service service = info.service; 9308 if (mSafeMode && (service.info.applicationInfo.flags 9309 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9310 return null; 9311 } 9312 PackageSetting ps = (PackageSetting) service.owner.mExtras; 9313 if (ps == null) { 9314 return null; 9315 } 9316 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 9317 ps.readUserState(userId), userId); 9318 if (si == null) { 9319 return null; 9320 } 9321 final ResolveInfo res = new ResolveInfo(); 9322 res.serviceInfo = si; 9323 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9324 res.filter = filter; 9325 } 9326 res.priority = info.getPriority(); 9327 res.preferredOrder = service.owner.mPreferredOrder; 9328 res.match = match; 9329 res.isDefault = info.hasDefault; 9330 res.labelRes = info.labelRes; 9331 res.nonLocalizedLabel = info.nonLocalizedLabel; 9332 res.icon = info.icon; 9333 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 9334 return res; 9335 } 9336 9337 @Override sortResults(List<ResolveInfo> results)9338 protected void sortResults(List<ResolveInfo> results) { 9339 Collections.sort(results, mResolvePrioritySorter); 9340 } 9341 9342 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)9343 protected void dumpFilter(PrintWriter out, String prefix, 9344 PackageParser.ServiceIntentInfo filter) { 9345 out.print(prefix); out.print( 9346 Integer.toHexString(System.identityHashCode(filter.service))); 9347 out.print(' '); 9348 filter.service.printComponentShortName(out); 9349 out.print(" filter "); 9350 out.println(Integer.toHexString(System.identityHashCode(filter))); 9351 } 9352 9353 @Override filterToLabel(PackageParser.ServiceIntentInfo filter)9354 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 9355 return filter.service; 9356 } 9357 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)9358 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9359 PackageParser.Service service = (PackageParser.Service)label; 9360 out.print(prefix); out.print( 9361 Integer.toHexString(System.identityHashCode(service))); 9362 out.print(' '); 9363 service.printComponentShortName(out); 9364 if (count > 1) { 9365 out.print(" ("); out.print(count); out.print(" filters)"); 9366 } 9367 out.println(); 9368 } 9369 9370 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9371 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9372 // final List<ResolveInfo> retList = Lists.newArrayList(); 9373 // while (i.hasNext()) { 9374 // final ResolveInfo resolveInfo = (ResolveInfo) i; 9375 // if (isEnabledLP(resolveInfo.serviceInfo)) { 9376 // retList.add(resolveInfo); 9377 // } 9378 // } 9379 // return retList; 9380 // } 9381 9382 // Keys are String (activity class name), values are Activity. 9383 private final ArrayMap<ComponentName, PackageParser.Service> mServices 9384 = new ArrayMap<ComponentName, PackageParser.Service>(); 9385 private int mFlags; 9386 }; 9387 9388 private final class ProviderIntentResolver 9389 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)9390 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9391 boolean defaultOnly, int userId) { 9392 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9393 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9394 } 9395 queryIntent(Intent intent, String resolvedType, int flags, int userId)9396 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9397 int userId) { 9398 if (!sUserManager.exists(userId)) 9399 return null; 9400 mFlags = flags; 9401 return super.queryIntent(intent, resolvedType, 9402 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9403 } 9404 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)9405 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9406 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 9407 if (!sUserManager.exists(userId)) 9408 return null; 9409 if (packageProviders == null) { 9410 return null; 9411 } 9412 mFlags = flags; 9413 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 9414 final int N = packageProviders.size(); 9415 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 9416 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 9417 9418 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 9419 for (int i = 0; i < N; ++i) { 9420 intentFilters = packageProviders.get(i).intents; 9421 if (intentFilters != null && intentFilters.size() > 0) { 9422 PackageParser.ProviderIntentInfo[] array = 9423 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 9424 intentFilters.toArray(array); 9425 listCut.add(array); 9426 } 9427 } 9428 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9429 } 9430 addProvider(PackageParser.Provider p)9431 public final void addProvider(PackageParser.Provider p) { 9432 if (mProviders.containsKey(p.getComponentName())) { 9433 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 9434 return; 9435 } 9436 9437 mProviders.put(p.getComponentName(), p); 9438 if (DEBUG_SHOW_INFO) { 9439 Log.v(TAG, " " 9440 + (p.info.nonLocalizedLabel != null 9441 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 9442 Log.v(TAG, " Class=" + p.info.name); 9443 } 9444 final int NI = p.intents.size(); 9445 int j; 9446 for (j = 0; j < NI; j++) { 9447 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 9448 if (DEBUG_SHOW_INFO) { 9449 Log.v(TAG, " IntentFilter:"); 9450 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9451 } 9452 if (!intent.debugCheck()) { 9453 Log.w(TAG, "==> For Provider " + p.info.name); 9454 } 9455 addFilter(intent); 9456 } 9457 } 9458 removeProvider(PackageParser.Provider p)9459 public final void removeProvider(PackageParser.Provider p) { 9460 mProviders.remove(p.getComponentName()); 9461 if (DEBUG_SHOW_INFO) { 9462 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 9463 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 9464 Log.v(TAG, " Class=" + p.info.name); 9465 } 9466 final int NI = p.intents.size(); 9467 int j; 9468 for (j = 0; j < NI; j++) { 9469 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 9470 if (DEBUG_SHOW_INFO) { 9471 Log.v(TAG, " IntentFilter:"); 9472 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9473 } 9474 removeFilter(intent); 9475 } 9476 } 9477 9478 @Override allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)9479 protected boolean allowFilterResult( 9480 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 9481 ProviderInfo filterPi = filter.provider.info; 9482 for (int i = dest.size() - 1; i >= 0; i--) { 9483 ProviderInfo destPi = dest.get(i).providerInfo; 9484 if (destPi.name == filterPi.name 9485 && destPi.packageName == filterPi.packageName) { 9486 return false; 9487 } 9488 } 9489 return true; 9490 } 9491 9492 @Override newArray(int size)9493 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 9494 return new PackageParser.ProviderIntentInfo[size]; 9495 } 9496 9497 @Override isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)9498 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 9499 if (!sUserManager.exists(userId)) 9500 return true; 9501 PackageParser.Package p = filter.provider.owner; 9502 if (p != null) { 9503 PackageSetting ps = (PackageSetting) p.mExtras; 9504 if (ps != null) { 9505 // System apps are never considered stopped for purposes of 9506 // filtering, because there may be no way for the user to 9507 // actually re-launch them. 9508 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9509 && ps.getStopped(userId); 9510 } 9511 } 9512 return false; 9513 } 9514 9515 @Override isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)9516 protected boolean isPackageForFilter(String packageName, 9517 PackageParser.ProviderIntentInfo info) { 9518 return packageName.equals(info.provider.owner.packageName); 9519 } 9520 9521 @Override newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)9522 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 9523 int match, int userId) { 9524 if (!sUserManager.exists(userId)) 9525 return null; 9526 final PackageParser.ProviderIntentInfo info = filter; 9527 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 9528 return null; 9529 } 9530 final PackageParser.Provider provider = info.provider; 9531 if (mSafeMode && (provider.info.applicationInfo.flags 9532 & ApplicationInfo.FLAG_SYSTEM) == 0) { 9533 return null; 9534 } 9535 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 9536 if (ps == null) { 9537 return null; 9538 } 9539 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 9540 ps.readUserState(userId), userId); 9541 if (pi == null) { 9542 return null; 9543 } 9544 final ResolveInfo res = new ResolveInfo(); 9545 res.providerInfo = pi; 9546 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 9547 res.filter = filter; 9548 } 9549 res.priority = info.getPriority(); 9550 res.preferredOrder = provider.owner.mPreferredOrder; 9551 res.match = match; 9552 res.isDefault = info.hasDefault; 9553 res.labelRes = info.labelRes; 9554 res.nonLocalizedLabel = info.nonLocalizedLabel; 9555 res.icon = info.icon; 9556 res.system = res.providerInfo.applicationInfo.isSystemApp(); 9557 return res; 9558 } 9559 9560 @Override sortResults(List<ResolveInfo> results)9561 protected void sortResults(List<ResolveInfo> results) { 9562 Collections.sort(results, mResolvePrioritySorter); 9563 } 9564 9565 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)9566 protected void dumpFilter(PrintWriter out, String prefix, 9567 PackageParser.ProviderIntentInfo filter) { 9568 out.print(prefix); 9569 out.print( 9570 Integer.toHexString(System.identityHashCode(filter.provider))); 9571 out.print(' '); 9572 filter.provider.printComponentShortName(out); 9573 out.print(" filter "); 9574 out.println(Integer.toHexString(System.identityHashCode(filter))); 9575 } 9576 9577 @Override filterToLabel(PackageParser.ProviderIntentInfo filter)9578 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 9579 return filter.provider; 9580 } 9581 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)9582 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9583 PackageParser.Provider provider = (PackageParser.Provider)label; 9584 out.print(prefix); out.print( 9585 Integer.toHexString(System.identityHashCode(provider))); 9586 out.print(' '); 9587 provider.printComponentShortName(out); 9588 if (count > 1) { 9589 out.print(" ("); out.print(count); out.print(" filters)"); 9590 } 9591 out.println(); 9592 } 9593 9594 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 9595 = new ArrayMap<ComponentName, PackageParser.Provider>(); 9596 private int mFlags; 9597 }; 9598 9599 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 9600 new Comparator<ResolveInfo>() { 9601 public int compare(ResolveInfo r1, ResolveInfo r2) { 9602 int v1 = r1.priority; 9603 int v2 = r2.priority; 9604 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 9605 if (v1 != v2) { 9606 return (v1 > v2) ? -1 : 1; 9607 } 9608 v1 = r1.preferredOrder; 9609 v2 = r2.preferredOrder; 9610 if (v1 != v2) { 9611 return (v1 > v2) ? -1 : 1; 9612 } 9613 if (r1.isDefault != r2.isDefault) { 9614 return r1.isDefault ? -1 : 1; 9615 } 9616 v1 = r1.match; 9617 v2 = r2.match; 9618 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 9619 if (v1 != v2) { 9620 return (v1 > v2) ? -1 : 1; 9621 } 9622 if (r1.system != r2.system) { 9623 return r1.system ? -1 : 1; 9624 } 9625 return 0; 9626 } 9627 }; 9628 9629 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 9630 new Comparator<ProviderInfo>() { 9631 public int compare(ProviderInfo p1, ProviderInfo p2) { 9632 final int v1 = p1.initOrder; 9633 final int v2 = p2.initOrder; 9634 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 9635 } 9636 }; 9637 sendPackageBroadcast(final String action, final String pkg, final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver, final int[] userIds)9638 final void sendPackageBroadcast(final String action, final String pkg, 9639 final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver, 9640 final int[] userIds) { 9641 mHandler.post(new Runnable() { 9642 @Override 9643 public void run() { 9644 try { 9645 final IActivityManager am = ActivityManagerNative.getDefault(); 9646 if (am == null) return; 9647 final int[] resolvedUserIds; 9648 if (userIds == null) { 9649 resolvedUserIds = am.getRunningUserIds(); 9650 } else { 9651 resolvedUserIds = userIds; 9652 } 9653 for (int id : resolvedUserIds) { 9654 final Intent intent = new Intent(action, 9655 pkg != null ? Uri.fromParts("package", pkg, null) : null); 9656 if (extras != null) { 9657 intent.putExtras(extras); 9658 } 9659 if (targetPkg != null) { 9660 intent.setPackage(targetPkg); 9661 } 9662 // Modify the UID when posting to other users 9663 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 9664 if (uid > 0 && UserHandle.getUserId(uid) != id) { 9665 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 9666 intent.putExtra(Intent.EXTRA_UID, uid); 9667 } 9668 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 9669 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 9670 if (DEBUG_BROADCASTS) { 9671 RuntimeException here = new RuntimeException("here"); 9672 here.fillInStackTrace(); 9673 Slog.d(TAG, "Sending to user " + id + ": " 9674 + intent.toShortString(false, true, false, false) 9675 + " " + intent.getExtras(), here); 9676 } 9677 am.broadcastIntent(null, intent, null, finishedReceiver, 9678 0, null, null, null, android.app.AppOpsManager.OP_NONE, 9679 null, finishedReceiver != null, false, id); 9680 } 9681 } catch (RemoteException ex) { 9682 } 9683 } 9684 }); 9685 } 9686 9687 /** 9688 * Check if the external storage media is available. This is true if there 9689 * is a mounted external storage medium or if the external storage is 9690 * emulated. 9691 */ isExternalMediaAvailable()9692 private boolean isExternalMediaAvailable() { 9693 return mMediaMounted || Environment.isExternalStorageEmulated(); 9694 } 9695 9696 @Override nextPackageToClean(PackageCleanItem lastPackage)9697 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 9698 // writer 9699 synchronized (mPackages) { 9700 if (!isExternalMediaAvailable()) { 9701 // If the external storage is no longer mounted at this point, 9702 // the caller may not have been able to delete all of this 9703 // packages files and can not delete any more. Bail. 9704 return null; 9705 } 9706 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 9707 if (lastPackage != null) { 9708 pkgs.remove(lastPackage); 9709 } 9710 if (pkgs.size() > 0) { 9711 return pkgs.get(0); 9712 } 9713 } 9714 return null; 9715 } 9716 schedulePackageCleaning(String packageName, int userId, boolean andCode)9717 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 9718 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 9719 userId, andCode ? 1 : 0, packageName); 9720 if (mSystemReady) { 9721 msg.sendToTarget(); 9722 } else { 9723 if (mPostSystemReadyMessages == null) { 9724 mPostSystemReadyMessages = new ArrayList<>(); 9725 } 9726 mPostSystemReadyMessages.add(msg); 9727 } 9728 } 9729 startCleaningPackages()9730 void startCleaningPackages() { 9731 // reader 9732 synchronized (mPackages) { 9733 if (!isExternalMediaAvailable()) { 9734 return; 9735 } 9736 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 9737 return; 9738 } 9739 } 9740 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 9741 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 9742 IActivityManager am = ActivityManagerNative.getDefault(); 9743 if (am != null) { 9744 try { 9745 am.startService(null, intent, null, mContext.getOpPackageName(), 9746 UserHandle.USER_OWNER); 9747 } catch (RemoteException e) { 9748 } 9749 } 9750 } 9751 9752 @Override installPackage(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride)9753 public void installPackage(String originPath, IPackageInstallObserver2 observer, 9754 int installFlags, String installerPackageName, VerificationParams verificationParams, 9755 String packageAbiOverride) { 9756 installPackageAsUser(originPath, observer, installFlags, installerPackageName, 9757 verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); 9758 } 9759 9760 @Override installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride, int userId)9761 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 9762 int installFlags, String installerPackageName, VerificationParams verificationParams, 9763 String packageAbiOverride, int userId) { 9764 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 9765 9766 final int callingUid = Binder.getCallingUid(); 9767 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 9768 9769 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 9770 try { 9771 if (observer != null) { 9772 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 9773 } 9774 } catch (RemoteException re) { 9775 } 9776 return; 9777 } 9778 9779 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 9780 installFlags |= PackageManager.INSTALL_FROM_ADB; 9781 9782 } else { 9783 // Caller holds INSTALL_PACKAGES permission, so we're less strict 9784 // about installerPackageName. 9785 9786 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 9787 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 9788 } 9789 9790 UserHandle user; 9791 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 9792 user = UserHandle.ALL; 9793 } else { 9794 user = new UserHandle(userId); 9795 } 9796 9797 // Only system components can circumvent runtime permissions when installing. 9798 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 9799 && mContext.checkCallingOrSelfPermission(Manifest.permission 9800 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 9801 throw new SecurityException("You need the " 9802 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 9803 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 9804 } 9805 9806 verificationParams.setInstallerUid(callingUid); 9807 9808 final File originFile = new File(originPath); 9809 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 9810 9811 final Message msg = mHandler.obtainMessage(INIT_COPY); 9812 msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName, 9813 null, verificationParams, user, packageAbiOverride, null); 9814 mHandler.sendMessage(msg); 9815 } 9816 installStage(String packageName, File stagedDir, String stagedCid, IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, String installerPackageName, int installerUid, UserHandle user)9817 void installStage(String packageName, File stagedDir, String stagedCid, 9818 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, 9819 String installerPackageName, int installerUid, UserHandle user) { 9820 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 9821 params.referrerUri, installerUid, null); 9822 verifParams.setInstallerUid(installerUid); 9823 9824 final OriginInfo origin; 9825 if (stagedDir != null) { 9826 origin = OriginInfo.fromStagedFile(stagedDir); 9827 } else { 9828 origin = OriginInfo.fromStagedContainer(stagedCid); 9829 } 9830 9831 final Message msg = mHandler.obtainMessage(INIT_COPY); 9832 msg.obj = new InstallParams(origin, null, observer, params.installFlags, 9833 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride, 9834 params.grantedRuntimePermissions); 9835 mHandler.sendMessage(msg); 9836 } 9837 sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)9838 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 9839 Bundle extras = new Bundle(1); 9840 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 9841 9842 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 9843 packageName, extras, null, null, new int[] {userId}); 9844 try { 9845 IActivityManager am = ActivityManagerNative.getDefault(); 9846 final boolean isSystem = 9847 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 9848 if (isSystem && am.isUserRunning(userId, false)) { 9849 // The just-installed/enabled app is bundled on the system, so presumed 9850 // to be able to run automatically without needing an explicit launch. 9851 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 9852 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 9853 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 9854 .setPackage(packageName); 9855 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 9856 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 9857 } 9858 } catch (RemoteException e) { 9859 // shouldn't happen 9860 Slog.w(TAG, "Unable to bootstrap installed package", e); 9861 } 9862 } 9863 9864 @Override setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)9865 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 9866 int userId) { 9867 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9868 PackageSetting pkgSetting; 9869 final int uid = Binder.getCallingUid(); 9870 enforceCrossUserPermission(uid, userId, true, true, 9871 "setApplicationHiddenSetting for user " + userId); 9872 9873 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 9874 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 9875 return false; 9876 } 9877 9878 long callingId = Binder.clearCallingIdentity(); 9879 try { 9880 boolean sendAdded = false; 9881 boolean sendRemoved = false; 9882 // writer 9883 synchronized (mPackages) { 9884 pkgSetting = mSettings.mPackages.get(packageName); 9885 if (pkgSetting == null) { 9886 return false; 9887 } 9888 if (pkgSetting.getHidden(userId) != hidden) { 9889 pkgSetting.setHidden(hidden, userId); 9890 mSettings.writePackageRestrictionsLPr(userId); 9891 if (hidden) { 9892 sendRemoved = true; 9893 } else { 9894 sendAdded = true; 9895 } 9896 } 9897 } 9898 if (sendAdded) { 9899 sendPackageAddedForUser(packageName, pkgSetting, userId); 9900 return true; 9901 } 9902 if (sendRemoved) { 9903 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 9904 "hiding pkg"); 9905 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 9906 return true; 9907 } 9908 } finally { 9909 Binder.restoreCallingIdentity(callingId); 9910 } 9911 return false; 9912 } 9913 sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)9914 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 9915 int userId) { 9916 final PackageRemovedInfo info = new PackageRemovedInfo(); 9917 info.removedPackage = packageName; 9918 info.removedUsers = new int[] {userId}; 9919 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 9920 info.sendBroadcast(false, false, false); 9921 } 9922 9923 /** 9924 * Returns true if application is not found or there was an error. Otherwise it returns 9925 * the hidden state of the package for the given user. 9926 */ 9927 @Override getApplicationHiddenSettingAsUser(String packageName, int userId)9928 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 9929 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9930 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 9931 false, "getApplicationHidden for user " + userId); 9932 PackageSetting pkgSetting; 9933 long callingId = Binder.clearCallingIdentity(); 9934 try { 9935 // writer 9936 synchronized (mPackages) { 9937 pkgSetting = mSettings.mPackages.get(packageName); 9938 if (pkgSetting == null) { 9939 return true; 9940 } 9941 return pkgSetting.getHidden(userId); 9942 } 9943 } finally { 9944 Binder.restoreCallingIdentity(callingId); 9945 } 9946 } 9947 9948 /** 9949 * @hide 9950 */ 9951 @Override installExistingPackageAsUser(String packageName, int userId)9952 public int installExistingPackageAsUser(String packageName, int userId) { 9953 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 9954 null); 9955 PackageSetting pkgSetting; 9956 final int uid = Binder.getCallingUid(); 9957 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 9958 + userId); 9959 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 9960 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 9961 } 9962 9963 long callingId = Binder.clearCallingIdentity(); 9964 try { 9965 boolean sendAdded = false; 9966 9967 // writer 9968 synchronized (mPackages) { 9969 pkgSetting = mSettings.mPackages.get(packageName); 9970 if (pkgSetting == null) { 9971 return PackageManager.INSTALL_FAILED_INVALID_URI; 9972 } 9973 if (!pkgSetting.getInstalled(userId)) { 9974 pkgSetting.setInstalled(true, userId); 9975 pkgSetting.setHidden(false, userId); 9976 mSettings.writePackageRestrictionsLPr(userId); 9977 sendAdded = true; 9978 } 9979 } 9980 9981 if (sendAdded) { 9982 sendPackageAddedForUser(packageName, pkgSetting, userId); 9983 } 9984 } finally { 9985 Binder.restoreCallingIdentity(callingId); 9986 } 9987 9988 return PackageManager.INSTALL_SUCCEEDED; 9989 } 9990 isUserRestricted(int userId, String restrictionKey)9991 boolean isUserRestricted(int userId, String restrictionKey) { 9992 Bundle restrictions = sUserManager.getUserRestrictions(userId); 9993 if (restrictions.getBoolean(restrictionKey, false)) { 9994 Log.w(TAG, "User is restricted: " + restrictionKey); 9995 return true; 9996 } 9997 return false; 9998 } 9999 10000 @Override verifyPendingInstall(int id, int verificationCode)10001 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 10002 mContext.enforceCallingOrSelfPermission( 10003 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10004 "Only package verification agents can verify applications"); 10005 10006 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10007 final PackageVerificationResponse response = new PackageVerificationResponse( 10008 verificationCode, Binder.getCallingUid()); 10009 msg.arg1 = id; 10010 msg.obj = response; 10011 mHandler.sendMessage(msg); 10012 } 10013 10014 @Override extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)10015 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 10016 long millisecondsToDelay) { 10017 mContext.enforceCallingOrSelfPermission( 10018 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10019 "Only package verification agents can extend verification timeouts"); 10020 10021 final PackageVerificationState state = mPendingVerification.get(id); 10022 final PackageVerificationResponse response = new PackageVerificationResponse( 10023 verificationCodeAtTimeout, Binder.getCallingUid()); 10024 10025 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 10026 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 10027 } 10028 if (millisecondsToDelay < 0) { 10029 millisecondsToDelay = 0; 10030 } 10031 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 10032 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 10033 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 10034 } 10035 10036 if ((state != null) && !state.timeoutExtended()) { 10037 state.extendTimeout(); 10038 10039 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10040 msg.arg1 = id; 10041 msg.obj = response; 10042 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 10043 } 10044 } 10045 broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)10046 private void broadcastPackageVerified(int verificationId, Uri packageUri, 10047 int verificationCode, UserHandle user) { 10048 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 10049 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 10050 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10051 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10052 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 10053 10054 mContext.sendBroadcastAsUser(intent, user, 10055 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 10056 } 10057 matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)10058 private ComponentName matchComponentForVerifier(String packageName, 10059 List<ResolveInfo> receivers) { 10060 ActivityInfo targetReceiver = null; 10061 10062 final int NR = receivers.size(); 10063 for (int i = 0; i < NR; i++) { 10064 final ResolveInfo info = receivers.get(i); 10065 if (info.activityInfo == null) { 10066 continue; 10067 } 10068 10069 if (packageName.equals(info.activityInfo.packageName)) { 10070 targetReceiver = info.activityInfo; 10071 break; 10072 } 10073 } 10074 10075 if (targetReceiver == null) { 10076 return null; 10077 } 10078 10079 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 10080 } 10081 matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)10082 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 10083 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 10084 if (pkgInfo.verifiers.length == 0) { 10085 return null; 10086 } 10087 10088 final int N = pkgInfo.verifiers.length; 10089 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 10090 for (int i = 0; i < N; i++) { 10091 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 10092 10093 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 10094 receivers); 10095 if (comp == null) { 10096 continue; 10097 } 10098 10099 final int verifierUid = getUidForVerifier(verifierInfo); 10100 if (verifierUid == -1) { 10101 continue; 10102 } 10103 10104 if (DEBUG_VERIFY) { 10105 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 10106 + " with the correct signature"); 10107 } 10108 sufficientVerifiers.add(comp); 10109 verificationState.addSufficientVerifier(verifierUid); 10110 } 10111 10112 return sufficientVerifiers; 10113 } 10114 getUidForVerifier(VerifierInfo verifierInfo)10115 private int getUidForVerifier(VerifierInfo verifierInfo) { 10116 synchronized (mPackages) { 10117 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 10118 if (pkg == null) { 10119 return -1; 10120 } else if (pkg.mSignatures.length != 1) { 10121 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10122 + " has more than one signature; ignoring"); 10123 return -1; 10124 } 10125 10126 /* 10127 * If the public key of the package's signature does not match 10128 * our expected public key, then this is a different package and 10129 * we should skip. 10130 */ 10131 10132 final byte[] expectedPublicKey; 10133 try { 10134 final Signature verifierSig = pkg.mSignatures[0]; 10135 final PublicKey publicKey = verifierSig.getPublicKey(); 10136 expectedPublicKey = publicKey.getEncoded(); 10137 } catch (CertificateException e) { 10138 return -1; 10139 } 10140 10141 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 10142 10143 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 10144 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10145 + " does not have the expected public key; ignoring"); 10146 return -1; 10147 } 10148 10149 return pkg.applicationInfo.uid; 10150 } 10151 } 10152 10153 @Override finishPackageInstall(int token)10154 public void finishPackageInstall(int token) { 10155 enforceSystemOrRoot("Only the system is allowed to finish installs"); 10156 10157 if (DEBUG_INSTALL) { 10158 Slog.v(TAG, "BM finishing package install for " + token); 10159 } 10160 10161 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 10162 mHandler.sendMessage(msg); 10163 } 10164 10165 /** 10166 * Get the verification agent timeout. 10167 * 10168 * @return verification timeout in milliseconds 10169 */ getVerificationTimeout()10170 private long getVerificationTimeout() { 10171 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 10172 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 10173 DEFAULT_VERIFICATION_TIMEOUT); 10174 } 10175 10176 /** 10177 * Get the default verification agent response code. 10178 * 10179 * @return default verification response code 10180 */ getDefaultVerificationResponse()10181 private int getDefaultVerificationResponse() { 10182 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10183 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 10184 DEFAULT_VERIFICATION_RESPONSE); 10185 } 10186 10187 /** 10188 * Check whether or not package verification has been enabled. 10189 * 10190 * @return true if verification should be performed 10191 */ isVerificationEnabled(int userId, int installFlags)10192 private boolean isVerificationEnabled(int userId, int installFlags) { 10193 if (!DEFAULT_VERIFY_ENABLE) { 10194 return false; 10195 } 10196 10197 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 10198 10199 // Check if installing from ADB 10200 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 10201 // Do not run verification in a test harness environment 10202 if (ActivityManager.isRunningInTestHarness()) { 10203 return false; 10204 } 10205 if (ensureVerifyAppsEnabled) { 10206 return true; 10207 } 10208 // Check if the developer does not want package verification for ADB installs 10209 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10210 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 10211 return false; 10212 } 10213 } 10214 10215 if (ensureVerifyAppsEnabled) { 10216 return true; 10217 } 10218 10219 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10220 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 10221 } 10222 10223 @Override verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)10224 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 10225 throws RemoteException { 10226 mContext.enforceCallingOrSelfPermission( 10227 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 10228 "Only intentfilter verification agents can verify applications"); 10229 10230 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 10231 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 10232 Binder.getCallingUid(), verificationCode, failedDomains); 10233 msg.arg1 = id; 10234 msg.obj = response; 10235 mHandler.sendMessage(msg); 10236 } 10237 10238 @Override getIntentVerificationStatus(String packageName, int userId)10239 public int getIntentVerificationStatus(String packageName, int userId) { 10240 synchronized (mPackages) { 10241 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 10242 } 10243 } 10244 10245 @Override updateIntentVerificationStatus(String packageName, int status, int userId)10246 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 10247 mContext.enforceCallingOrSelfPermission( 10248 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10249 10250 boolean result = false; 10251 synchronized (mPackages) { 10252 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 10253 } 10254 if (result) { 10255 scheduleWritePackageRestrictionsLocked(userId); 10256 } 10257 return result; 10258 } 10259 10260 @Override getIntentFilterVerifications(String packageName)10261 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 10262 synchronized (mPackages) { 10263 return mSettings.getIntentFilterVerificationsLPr(packageName); 10264 } 10265 } 10266 10267 @Override getAllIntentFilters(String packageName)10268 public List<IntentFilter> getAllIntentFilters(String packageName) { 10269 if (TextUtils.isEmpty(packageName)) { 10270 return Collections.<IntentFilter>emptyList(); 10271 } 10272 synchronized (mPackages) { 10273 PackageParser.Package pkg = mPackages.get(packageName); 10274 if (pkg == null || pkg.activities == null) { 10275 return Collections.<IntentFilter>emptyList(); 10276 } 10277 final int count = pkg.activities.size(); 10278 ArrayList<IntentFilter> result = new ArrayList<>(); 10279 for (int n=0; n<count; n++) { 10280 PackageParser.Activity activity = pkg.activities.get(n); 10281 if (activity.intents != null || activity.intents.size() > 0) { 10282 result.addAll(activity.intents); 10283 } 10284 } 10285 return result; 10286 } 10287 } 10288 10289 @Override setDefaultBrowserPackageName(String packageName, int userId)10290 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 10291 mContext.enforceCallingOrSelfPermission( 10292 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10293 10294 synchronized (mPackages) { 10295 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 10296 if (packageName != null) { 10297 result |= updateIntentVerificationStatus(packageName, 10298 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 10299 userId); 10300 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 10301 packageName, userId); 10302 } 10303 return result; 10304 } 10305 } 10306 10307 @Override getDefaultBrowserPackageName(int userId)10308 public String getDefaultBrowserPackageName(int userId) { 10309 synchronized (mPackages) { 10310 return mSettings.getDefaultBrowserPackageNameLPw(userId); 10311 } 10312 } 10313 10314 /** 10315 * Get the "allow unknown sources" setting. 10316 * 10317 * @return the current "allow unknown sources" setting 10318 */ getUnknownSourcesSettings()10319 private int getUnknownSourcesSettings() { 10320 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10321 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 10322 -1); 10323 } 10324 10325 @Override setInstallerPackageName(String targetPackage, String installerPackageName)10326 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 10327 final int uid = Binder.getCallingUid(); 10328 // writer 10329 synchronized (mPackages) { 10330 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 10331 if (targetPackageSetting == null) { 10332 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 10333 } 10334 10335 PackageSetting installerPackageSetting; 10336 if (installerPackageName != null) { 10337 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 10338 if (installerPackageSetting == null) { 10339 throw new IllegalArgumentException("Unknown installer package: " 10340 + installerPackageName); 10341 } 10342 } else { 10343 installerPackageSetting = null; 10344 } 10345 10346 Signature[] callerSignature; 10347 Object obj = mSettings.getUserIdLPr(uid); 10348 if (obj != null) { 10349 if (obj instanceof SharedUserSetting) { 10350 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 10351 } else if (obj instanceof PackageSetting) { 10352 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 10353 } else { 10354 throw new SecurityException("Bad object " + obj + " for uid " + uid); 10355 } 10356 } else { 10357 throw new SecurityException("Unknown calling uid " + uid); 10358 } 10359 10360 // Verify: can't set installerPackageName to a package that is 10361 // not signed with the same cert as the caller. 10362 if (installerPackageSetting != null) { 10363 if (compareSignatures(callerSignature, 10364 installerPackageSetting.signatures.mSignatures) 10365 != PackageManager.SIGNATURE_MATCH) { 10366 throw new SecurityException( 10367 "Caller does not have same cert as new installer package " 10368 + installerPackageName); 10369 } 10370 } 10371 10372 // Verify: if target already has an installer package, it must 10373 // be signed with the same cert as the caller. 10374 if (targetPackageSetting.installerPackageName != null) { 10375 PackageSetting setting = mSettings.mPackages.get( 10376 targetPackageSetting.installerPackageName); 10377 // If the currently set package isn't valid, then it's always 10378 // okay to change it. 10379 if (setting != null) { 10380 if (compareSignatures(callerSignature, 10381 setting.signatures.mSignatures) 10382 != PackageManager.SIGNATURE_MATCH) { 10383 throw new SecurityException( 10384 "Caller does not have same cert as old installer package " 10385 + targetPackageSetting.installerPackageName); 10386 } 10387 } 10388 } 10389 10390 // Okay! 10391 targetPackageSetting.installerPackageName = installerPackageName; 10392 scheduleWriteSettingsLocked(); 10393 } 10394 } 10395 processPendingInstall(final InstallArgs args, final int currentStatus)10396 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 10397 // Queue up an async operation since the package installation may take a little while. 10398 mHandler.post(new Runnable() { 10399 public void run() { 10400 mHandler.removeCallbacks(this); 10401 // Result object to be returned 10402 PackageInstalledInfo res = new PackageInstalledInfo(); 10403 res.returnCode = currentStatus; 10404 res.uid = -1; 10405 res.pkg = null; 10406 res.removedInfo = new PackageRemovedInfo(); 10407 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 10408 args.doPreInstall(res.returnCode); 10409 synchronized (mInstallLock) { 10410 installPackageLI(args, res); 10411 } 10412 args.doPostInstall(res.returnCode, res.uid); 10413 } 10414 10415 // A restore should be performed at this point if (a) the install 10416 // succeeded, (b) the operation is not an update, and (c) the new 10417 // package has not opted out of backup participation. 10418 final boolean update = res.removedInfo.removedPackage != null; 10419 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 10420 boolean doRestore = !update 10421 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 10422 10423 // Set up the post-install work request bookkeeping. This will be used 10424 // and cleaned up by the post-install event handling regardless of whether 10425 // there's a restore pass performed. Token values are >= 1. 10426 int token; 10427 if (mNextInstallToken < 0) mNextInstallToken = 1; 10428 token = mNextInstallToken++; 10429 10430 PostInstallData data = new PostInstallData(args, res); 10431 mRunningInstalls.put(token, data); 10432 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 10433 10434 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 10435 // Pass responsibility to the Backup Manager. It will perform a 10436 // restore if appropriate, then pass responsibility back to the 10437 // Package Manager to run the post-install observer callbacks 10438 // and broadcasts. 10439 IBackupManager bm = IBackupManager.Stub.asInterface( 10440 ServiceManager.getService(Context.BACKUP_SERVICE)); 10441 if (bm != null) { 10442 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 10443 + " to BM for possible restore"); 10444 try { 10445 if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { 10446 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 10447 } else { 10448 doRestore = false; 10449 } 10450 } catch (RemoteException e) { 10451 // can't happen; the backup manager is local 10452 } catch (Exception e) { 10453 Slog.e(TAG, "Exception trying to enqueue restore", e); 10454 doRestore = false; 10455 } 10456 } else { 10457 Slog.e(TAG, "Backup Manager not found!"); 10458 doRestore = false; 10459 } 10460 } 10461 10462 if (!doRestore) { 10463 // No restore possible, or the Backup Manager was mysteriously not 10464 // available -- just fire the post-install work request directly. 10465 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 10466 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 10467 mHandler.sendMessage(msg); 10468 } 10469 } 10470 }); 10471 } 10472 10473 private abstract class HandlerParams { 10474 private static final int MAX_RETRIES = 4; 10475 10476 /** 10477 * Number of times startCopy() has been attempted and had a non-fatal 10478 * error. 10479 */ 10480 private int mRetries = 0; 10481 10482 /** User handle for the user requesting the information or installation. */ 10483 private final UserHandle mUser; 10484 HandlerParams(UserHandle user)10485 HandlerParams(UserHandle user) { 10486 mUser = user; 10487 } 10488 getUser()10489 UserHandle getUser() { 10490 return mUser; 10491 } 10492 startCopy()10493 final boolean startCopy() { 10494 boolean res; 10495 try { 10496 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 10497 10498 if (++mRetries > MAX_RETRIES) { 10499 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 10500 mHandler.sendEmptyMessage(MCS_GIVE_UP); 10501 handleServiceError(); 10502 return false; 10503 } else { 10504 handleStartCopy(); 10505 res = true; 10506 } 10507 } catch (RemoteException e) { 10508 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 10509 mHandler.sendEmptyMessage(MCS_RECONNECT); 10510 res = false; 10511 } 10512 handleReturnCode(); 10513 return res; 10514 } 10515 serviceError()10516 final void serviceError() { 10517 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 10518 handleServiceError(); 10519 handleReturnCode(); 10520 } 10521 handleStartCopy()10522 abstract void handleStartCopy() throws RemoteException; handleServiceError()10523 abstract void handleServiceError(); handleReturnCode()10524 abstract void handleReturnCode(); 10525 } 10526 10527 class MeasureParams extends HandlerParams { 10528 private final PackageStats mStats; 10529 private boolean mSuccess; 10530 10531 private final IPackageStatsObserver mObserver; 10532 MeasureParams(PackageStats stats, IPackageStatsObserver observer)10533 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 10534 super(new UserHandle(stats.userHandle)); 10535 mObserver = observer; 10536 mStats = stats; 10537 } 10538 10539 @Override toString()10540 public String toString() { 10541 return "MeasureParams{" 10542 + Integer.toHexString(System.identityHashCode(this)) 10543 + " " + mStats.packageName + "}"; 10544 } 10545 10546 @Override handleStartCopy()10547 void handleStartCopy() throws RemoteException { 10548 synchronized (mInstallLock) { 10549 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 10550 } 10551 10552 if (mSuccess) { 10553 final boolean mounted; 10554 if (Environment.isExternalStorageEmulated()) { 10555 mounted = true; 10556 } else { 10557 final String status = Environment.getExternalStorageState(); 10558 mounted = (Environment.MEDIA_MOUNTED.equals(status) 10559 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 10560 } 10561 10562 if (mounted) { 10563 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 10564 10565 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 10566 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 10567 10568 mStats.externalDataSize = calculateDirectorySize(mContainerService, 10569 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 10570 10571 // Always subtract cache size, since it's a subdirectory 10572 mStats.externalDataSize -= mStats.externalCacheSize; 10573 10574 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 10575 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 10576 10577 mStats.externalObbSize = calculateDirectorySize(mContainerService, 10578 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 10579 } 10580 } 10581 } 10582 10583 @Override handleReturnCode()10584 void handleReturnCode() { 10585 if (mObserver != null) { 10586 try { 10587 mObserver.onGetStatsCompleted(mStats, mSuccess); 10588 } catch (RemoteException e) { 10589 Slog.i(TAG, "Observer no longer exists."); 10590 } 10591 } 10592 } 10593 10594 @Override handleServiceError()10595 void handleServiceError() { 10596 Slog.e(TAG, "Could not measure application " + mStats.packageName 10597 + " external storage"); 10598 } 10599 } 10600 calculateDirectorySize(IMediaContainerService mcs, File[] paths)10601 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 10602 throws RemoteException { 10603 long result = 0; 10604 for (File path : paths) { 10605 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 10606 } 10607 return result; 10608 } 10609 clearDirectory(IMediaContainerService mcs, File[] paths)10610 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 10611 for (File path : paths) { 10612 try { 10613 mcs.clearDirectory(path.getAbsolutePath()); 10614 } catch (RemoteException e) { 10615 } 10616 } 10617 } 10618 10619 static class OriginInfo { 10620 /** 10621 * Location where install is coming from, before it has been 10622 * copied/renamed into place. This could be a single monolithic APK 10623 * file, or a cluster directory. This location may be untrusted. 10624 */ 10625 final File file; 10626 final String cid; 10627 10628 /** 10629 * Flag indicating that {@link #file} or {@link #cid} has already been 10630 * staged, meaning downstream users don't need to defensively copy the 10631 * contents. 10632 */ 10633 final boolean staged; 10634 10635 /** 10636 * Flag indicating that {@link #file} or {@link #cid} is an already 10637 * installed app that is being moved. 10638 */ 10639 final boolean existing; 10640 10641 final String resolvedPath; 10642 final File resolvedFile; 10643 fromNothing()10644 static OriginInfo fromNothing() { 10645 return new OriginInfo(null, null, false, false); 10646 } 10647 fromUntrustedFile(File file)10648 static OriginInfo fromUntrustedFile(File file) { 10649 return new OriginInfo(file, null, false, false); 10650 } 10651 fromExistingFile(File file)10652 static OriginInfo fromExistingFile(File file) { 10653 return new OriginInfo(file, null, false, true); 10654 } 10655 fromStagedFile(File file)10656 static OriginInfo fromStagedFile(File file) { 10657 return new OriginInfo(file, null, true, false); 10658 } 10659 fromStagedContainer(String cid)10660 static OriginInfo fromStagedContainer(String cid) { 10661 return new OriginInfo(null, cid, true, false); 10662 } 10663 OriginInfo(File file, String cid, boolean staged, boolean existing)10664 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 10665 this.file = file; 10666 this.cid = cid; 10667 this.staged = staged; 10668 this.existing = existing; 10669 10670 if (cid != null) { 10671 resolvedPath = PackageHelper.getSdDir(cid); 10672 resolvedFile = new File(resolvedPath); 10673 } else if (file != null) { 10674 resolvedPath = file.getAbsolutePath(); 10675 resolvedFile = file; 10676 } else { 10677 resolvedPath = null; 10678 resolvedFile = null; 10679 } 10680 } 10681 } 10682 10683 class MoveInfo { 10684 final int moveId; 10685 final String fromUuid; 10686 final String toUuid; 10687 final String packageName; 10688 final String dataAppName; 10689 final int appId; 10690 final String seinfo; 10691 MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, String dataAppName, int appId, String seinfo)10692 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 10693 String dataAppName, int appId, String seinfo) { 10694 this.moveId = moveId; 10695 this.fromUuid = fromUuid; 10696 this.toUuid = toUuid; 10697 this.packageName = packageName; 10698 this.dataAppName = dataAppName; 10699 this.appId = appId; 10700 this.seinfo = seinfo; 10701 } 10702 } 10703 10704 class InstallParams extends HandlerParams { 10705 final OriginInfo origin; 10706 final MoveInfo move; 10707 final IPackageInstallObserver2 observer; 10708 int installFlags; 10709 final String installerPackageName; 10710 final String volumeUuid; 10711 final VerificationParams verificationParams; 10712 private InstallArgs mArgs; 10713 private int mRet; 10714 final String packageAbiOverride; 10715 final String[] grantedRuntimePermissions; 10716 10717 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, VerificationParams verificationParams, UserHandle user, String packageAbiOverride, String[] grantedPermissions)10718 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 10719 int installFlags, String installerPackageName, String volumeUuid, 10720 VerificationParams verificationParams, UserHandle user, String packageAbiOverride, 10721 String[] grantedPermissions) { 10722 super(user); 10723 this.origin = origin; 10724 this.move = move; 10725 this.observer = observer; 10726 this.installFlags = installFlags; 10727 this.installerPackageName = installerPackageName; 10728 this.volumeUuid = volumeUuid; 10729 this.verificationParams = verificationParams; 10730 this.packageAbiOverride = packageAbiOverride; 10731 this.grantedRuntimePermissions = grantedPermissions; 10732 } 10733 10734 @Override toString()10735 public String toString() { 10736 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 10737 + " file=" + origin.file + " cid=" + origin.cid + "}"; 10738 } 10739 getManifestDigest()10740 public ManifestDigest getManifestDigest() { 10741 if (verificationParams == null) { 10742 return null; 10743 } 10744 return verificationParams.getManifestDigest(); 10745 } 10746 installLocationPolicy(PackageInfoLite pkgLite)10747 private int installLocationPolicy(PackageInfoLite pkgLite) { 10748 String packageName = pkgLite.packageName; 10749 int installLocation = pkgLite.installLocation; 10750 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10751 // reader 10752 synchronized (mPackages) { 10753 PackageParser.Package pkg = mPackages.get(packageName); 10754 if (pkg != null) { 10755 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 10756 // Check for downgrading. 10757 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 10758 try { 10759 checkDowngrade(pkg, pkgLite); 10760 } catch (PackageManagerException e) { 10761 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 10762 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 10763 } 10764 } 10765 // Check for updated system application. 10766 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10767 if (onSd) { 10768 Slog.w(TAG, "Cannot install update to system app on sdcard"); 10769 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 10770 } 10771 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10772 } else { 10773 if (onSd) { 10774 // Install flag overrides everything. 10775 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10776 } 10777 // If current upgrade specifies particular preference 10778 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 10779 // Application explicitly specified internal. 10780 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10781 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 10782 // App explictly prefers external. Let policy decide 10783 } else { 10784 // Prefer previous location 10785 if (isExternal(pkg)) { 10786 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10787 } 10788 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 10789 } 10790 } 10791 } else { 10792 // Invalid install. Return error code 10793 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 10794 } 10795 } 10796 } 10797 // All the special cases have been taken care of. 10798 // Return result based on recommended install location. 10799 if (onSd) { 10800 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 10801 } 10802 return pkgLite.recommendedInstallLocation; 10803 } 10804 10805 /* 10806 * Invoke remote method to get package information and install 10807 * location values. Override install location based on default 10808 * policy if needed and then create install arguments based 10809 * on the install location. 10810 */ handleStartCopy()10811 public void handleStartCopy() throws RemoteException { 10812 int ret = PackageManager.INSTALL_SUCCEEDED; 10813 10814 // If we're already staged, we've firmly committed to an install location 10815 if (origin.staged) { 10816 if (origin.file != null) { 10817 installFlags |= PackageManager.INSTALL_INTERNAL; 10818 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 10819 } else if (origin.cid != null) { 10820 installFlags |= PackageManager.INSTALL_EXTERNAL; 10821 installFlags &= ~PackageManager.INSTALL_INTERNAL; 10822 } else { 10823 throw new IllegalStateException("Invalid stage location"); 10824 } 10825 } 10826 10827 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10828 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 10829 10830 PackageInfoLite pkgLite = null; 10831 10832 if (onInt && onSd) { 10833 // Check if both bits are set. 10834 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 10835 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 10836 } else { 10837 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 10838 packageAbiOverride); 10839 10840 /* 10841 * If we have too little free space, try to free cache 10842 * before giving up. 10843 */ 10844 if (!origin.staged && pkgLite.recommendedInstallLocation 10845 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 10846 // TODO: focus freeing disk space on the target device 10847 final StorageManager storage = StorageManager.from(mContext); 10848 final long lowThreshold = storage.getStorageLowBytes( 10849 Environment.getDataDirectory()); 10850 10851 final long sizeBytes = mContainerService.calculateInstalledSize( 10852 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 10853 10854 if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) { 10855 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 10856 installFlags, packageAbiOverride); 10857 } 10858 10859 /* 10860 * The cache free must have deleted the file we 10861 * downloaded to install. 10862 * 10863 * TODO: fix the "freeCache" call to not delete 10864 * the file we care about. 10865 */ 10866 if (pkgLite.recommendedInstallLocation 10867 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 10868 pkgLite.recommendedInstallLocation 10869 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 10870 } 10871 } 10872 } 10873 10874 if (ret == PackageManager.INSTALL_SUCCEEDED) { 10875 int loc = pkgLite.recommendedInstallLocation; 10876 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 10877 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 10878 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 10879 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 10880 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 10881 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10882 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 10883 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 10884 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 10885 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 10886 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 10887 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 10888 } else { 10889 // Override with defaults if needed. 10890 loc = installLocationPolicy(pkgLite); 10891 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 10892 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 10893 } else if (!onSd && !onInt) { 10894 // Override install location with flags 10895 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 10896 // Set the flag to install on external media. 10897 installFlags |= PackageManager.INSTALL_EXTERNAL; 10898 installFlags &= ~PackageManager.INSTALL_INTERNAL; 10899 } else { 10900 // Make sure the flag for installing on external 10901 // media is unset 10902 installFlags |= PackageManager.INSTALL_INTERNAL; 10903 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 10904 } 10905 } 10906 } 10907 } 10908 10909 final InstallArgs args = createInstallArgs(this); 10910 mArgs = args; 10911 10912 if (ret == PackageManager.INSTALL_SUCCEEDED) { 10913 /* 10914 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 10915 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 10916 */ 10917 int userIdentifier = getUser().getIdentifier(); 10918 if (userIdentifier == UserHandle.USER_ALL 10919 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) { 10920 userIdentifier = UserHandle.USER_OWNER; 10921 } 10922 10923 /* 10924 * Determine if we have any installed package verifiers. If we 10925 * do, then we'll defer to them to verify the packages. 10926 */ 10927 final int requiredUid = mRequiredVerifierPackage == null ? -1 10928 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 10929 if (!origin.existing && requiredUid != -1 10930 && isVerificationEnabled(userIdentifier, installFlags)) { 10931 final Intent verification = new Intent( 10932 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 10933 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10934 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 10935 PACKAGE_MIME_TYPE); 10936 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10937 10938 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 10939 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 10940 0 /* TODO: Which userId? */); 10941 10942 if (DEBUG_VERIFY) { 10943 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 10944 + verification.toString() + " with " + pkgLite.verifiers.length 10945 + " optional verifiers"); 10946 } 10947 10948 final int verificationId = mPendingVerificationToken++; 10949 10950 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10951 10952 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 10953 installerPackageName); 10954 10955 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 10956 installFlags); 10957 10958 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 10959 pkgLite.packageName); 10960 10961 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 10962 pkgLite.versionCode); 10963 10964 if (verificationParams != null) { 10965 if (verificationParams.getVerificationURI() != null) { 10966 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 10967 verificationParams.getVerificationURI()); 10968 } 10969 if (verificationParams.getOriginatingURI() != null) { 10970 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 10971 verificationParams.getOriginatingURI()); 10972 } 10973 if (verificationParams.getReferrer() != null) { 10974 verification.putExtra(Intent.EXTRA_REFERRER, 10975 verificationParams.getReferrer()); 10976 } 10977 if (verificationParams.getOriginatingUid() >= 0) { 10978 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 10979 verificationParams.getOriginatingUid()); 10980 } 10981 if (verificationParams.getInstallerUid() >= 0) { 10982 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 10983 verificationParams.getInstallerUid()); 10984 } 10985 } 10986 10987 final PackageVerificationState verificationState = new PackageVerificationState( 10988 requiredUid, args); 10989 10990 mPendingVerification.append(verificationId, verificationState); 10991 10992 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 10993 receivers, verificationState); 10994 10995 // Apps installed for "all" users use the device owner to verify the app 10996 UserHandle verifierUser = getUser(); 10997 if (verifierUser == UserHandle.ALL) { 10998 verifierUser = UserHandle.OWNER; 10999 } 11000 11001 /* 11002 * If any sufficient verifiers were listed in the package 11003 * manifest, attempt to ask them. 11004 */ 11005 if (sufficientVerifiers != null) { 11006 final int N = sufficientVerifiers.size(); 11007 if (N == 0) { 11008 Slog.i(TAG, "Additional verifiers required, but none installed."); 11009 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 11010 } else { 11011 for (int i = 0; i < N; i++) { 11012 final ComponentName verifierComponent = sufficientVerifiers.get(i); 11013 11014 final Intent sufficientIntent = new Intent(verification); 11015 sufficientIntent.setComponent(verifierComponent); 11016 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 11017 } 11018 } 11019 } 11020 11021 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 11022 mRequiredVerifierPackage, receivers); 11023 if (ret == PackageManager.INSTALL_SUCCEEDED 11024 && mRequiredVerifierPackage != null) { 11025 /* 11026 * Send the intent to the required verification agent, 11027 * but only start the verification timeout after the 11028 * target BroadcastReceivers have run. 11029 */ 11030 verification.setComponent(requiredVerifierComponent); 11031 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 11032 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11033 new BroadcastReceiver() { 11034 @Override 11035 public void onReceive(Context context, Intent intent) { 11036 final Message msg = mHandler 11037 .obtainMessage(CHECK_PENDING_VERIFICATION); 11038 msg.arg1 = verificationId; 11039 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 11040 } 11041 }, null, 0, null, null); 11042 11043 /* 11044 * We don't want the copy to proceed until verification 11045 * succeeds, so null out this field. 11046 */ 11047 mArgs = null; 11048 } 11049 } else { 11050 /* 11051 * No package verification is enabled, so immediately start 11052 * the remote call to initiate copy using temporary file. 11053 */ 11054 ret = args.copyApk(mContainerService, true); 11055 } 11056 } 11057 11058 mRet = ret; 11059 } 11060 11061 @Override handleReturnCode()11062 void handleReturnCode() { 11063 // If mArgs is null, then MCS couldn't be reached. When it 11064 // reconnects, it will try again to install. At that point, this 11065 // will succeed. 11066 if (mArgs != null) { 11067 processPendingInstall(mArgs, mRet); 11068 } 11069 } 11070 11071 @Override handleServiceError()11072 void handleServiceError() { 11073 mArgs = createInstallArgs(this); 11074 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11075 } 11076 isForwardLocked()11077 public boolean isForwardLocked() { 11078 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11079 } 11080 } 11081 11082 /** 11083 * Used during creation of InstallArgs 11084 * 11085 * @param installFlags package installation flags 11086 * @return true if should be installed on external storage 11087 */ installOnExternalAsec(int installFlags)11088 private static boolean installOnExternalAsec(int installFlags) { 11089 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 11090 return false; 11091 } 11092 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 11093 return true; 11094 } 11095 return false; 11096 } 11097 11098 /** 11099 * Used during creation of InstallArgs 11100 * 11101 * @param installFlags package installation flags 11102 * @return true if should be installed as forward locked 11103 */ installForwardLocked(int installFlags)11104 private static boolean installForwardLocked(int installFlags) { 11105 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11106 } 11107 createInstallArgs(InstallParams params)11108 private InstallArgs createInstallArgs(InstallParams params) { 11109 if (params.move != null) { 11110 return new MoveInstallArgs(params); 11111 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 11112 return new AsecInstallArgs(params); 11113 } else { 11114 return new FileInstallArgs(params); 11115 } 11116 } 11117 11118 /** 11119 * Create args that describe an existing installed package. Typically used 11120 * when cleaning up old installs, or used as a move source. 11121 */ createInstallArgsForExisting(int installFlags, String codePath, String resourcePath, String[] instructionSets)11122 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 11123 String resourcePath, String[] instructionSets) { 11124 final boolean isInAsec; 11125 if (installOnExternalAsec(installFlags)) { 11126 /* Apps on SD card are always in ASEC containers. */ 11127 isInAsec = true; 11128 } else if (installForwardLocked(installFlags) 11129 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 11130 /* 11131 * Forward-locked apps are only in ASEC containers if they're the 11132 * new style 11133 */ 11134 isInAsec = true; 11135 } else { 11136 isInAsec = false; 11137 } 11138 11139 if (isInAsec) { 11140 return new AsecInstallArgs(codePath, instructionSets, 11141 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 11142 } else { 11143 return new FileInstallArgs(codePath, resourcePath, instructionSets); 11144 } 11145 } 11146 11147 static abstract class InstallArgs { 11148 /** @see InstallParams#origin */ 11149 final OriginInfo origin; 11150 /** @see InstallParams#move */ 11151 final MoveInfo move; 11152 11153 final IPackageInstallObserver2 observer; 11154 // Always refers to PackageManager flags only 11155 final int installFlags; 11156 final String installerPackageName; 11157 final String volumeUuid; 11158 final ManifestDigest manifestDigest; 11159 final UserHandle user; 11160 final String abiOverride; 11161 final String[] installGrantPermissions; 11162 11163 // The list of instruction sets supported by this app. This is currently 11164 // only used during the rmdex() phase to clean up resources. We can get rid of this 11165 // if we move dex files under the common app path. 11166 /* nullable */ String[] instructionSets; 11167 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, String abiOverride, String[] installGrantPermissions)11168 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 11169 int installFlags, String installerPackageName, String volumeUuid, 11170 ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, 11171 String abiOverride, String[] installGrantPermissions) { 11172 this.origin = origin; 11173 this.move = move; 11174 this.installFlags = installFlags; 11175 this.observer = observer; 11176 this.installerPackageName = installerPackageName; 11177 this.volumeUuid = volumeUuid; 11178 this.manifestDigest = manifestDigest; 11179 this.user = user; 11180 this.instructionSets = instructionSets; 11181 this.abiOverride = abiOverride; 11182 this.installGrantPermissions = installGrantPermissions; 11183 } 11184 copyApk(IMediaContainerService imcs, boolean temp)11185 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; doPreInstall(int status)11186 abstract int doPreInstall(int status); 11187 11188 /** 11189 * Rename package into final resting place. All paths on the given 11190 * scanned package should be updated to reflect the rename. 11191 */ doRename(int status, PackageParser.Package pkg, String oldCodePath)11192 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); doPostInstall(int status, int uid)11193 abstract int doPostInstall(int status, int uid); 11194 11195 /** @see PackageSettingBase#codePathString */ getCodePath()11196 abstract String getCodePath(); 11197 /** @see PackageSettingBase#resourcePathString */ getResourcePath()11198 abstract String getResourcePath(); 11199 11200 // Need installer lock especially for dex file removal. cleanUpResourcesLI()11201 abstract void cleanUpResourcesLI(); doPostDeleteLI(boolean delete)11202 abstract boolean doPostDeleteLI(boolean delete); 11203 11204 /** 11205 * Called before the source arguments are copied. This is used mostly 11206 * for MoveParams when it needs to read the source file to put it in the 11207 * destination. 11208 */ doPreCopy()11209 int doPreCopy() { 11210 return PackageManager.INSTALL_SUCCEEDED; 11211 } 11212 11213 /** 11214 * Called after the source arguments are copied. This is used mostly for 11215 * MoveParams when it needs to read the source file to put it in the 11216 * destination. 11217 */ doPostCopy(int uid)11218 int doPostCopy(int uid) { 11219 return PackageManager.INSTALL_SUCCEEDED; 11220 } 11221 isFwdLocked()11222 protected boolean isFwdLocked() { 11223 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11224 } 11225 isExternalAsec()11226 protected boolean isExternalAsec() { 11227 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11228 } 11229 getUser()11230 UserHandle getUser() { 11231 return user; 11232 } 11233 } 11234 removeDexFiles(List<String> allCodePaths, String[] instructionSets)11235 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 11236 if (!allCodePaths.isEmpty()) { 11237 if (instructionSets == null) { 11238 throw new IllegalStateException("instructionSet == null"); 11239 } 11240 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 11241 for (String codePath : allCodePaths) { 11242 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 11243 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 11244 if (retCode < 0) { 11245 Slog.w(TAG, "Couldn't remove dex file for package: " 11246 + " at location " + codePath + ", retcode=" + retCode); 11247 // we don't consider this to be a failure of the core package deletion 11248 } 11249 } 11250 } 11251 } 11252 } 11253 11254 /** 11255 * Logic to handle installation of non-ASEC applications, including copying 11256 * and renaming logic. 11257 */ 11258 class FileInstallArgs extends InstallArgs { 11259 private File codeFile; 11260 private File resourceFile; 11261 11262 // Example topology: 11263 // /data/app/com.example/base.apk 11264 // /data/app/com.example/split_foo.apk 11265 // /data/app/com.example/lib/arm/libfoo.so 11266 // /data/app/com.example/lib/arm64/libfoo.so 11267 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 11268 11269 /** New install */ FileInstallArgs(InstallParams params)11270 FileInstallArgs(InstallParams params) { 11271 super(params.origin, params.move, params.observer, params.installFlags, 11272 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11273 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11274 params.grantedRuntimePermissions); 11275 if (isFwdLocked()) { 11276 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 11277 } 11278 } 11279 11280 /** Existing install */ FileInstallArgs(String codePath, String resourcePath, String[] instructionSets)11281 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 11282 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets, 11283 null, null); 11284 this.codeFile = (codePath != null) ? new File(codePath) : null; 11285 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 11286 } 11287 copyApk(IMediaContainerService imcs, boolean temp)11288 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11289 if (origin.staged) { 11290 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 11291 codeFile = origin.file; 11292 resourceFile = origin.file; 11293 return PackageManager.INSTALL_SUCCEEDED; 11294 } 11295 11296 try { 11297 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid); 11298 codeFile = tempDir; 11299 resourceFile = tempDir; 11300 } catch (IOException e) { 11301 Slog.w(TAG, "Failed to create copy file: " + e); 11302 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11303 } 11304 11305 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 11306 @Override 11307 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 11308 if (!FileUtils.isValidExtFilename(name)) { 11309 throw new IllegalArgumentException("Invalid filename: " + name); 11310 } 11311 try { 11312 final File file = new File(codeFile, name); 11313 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 11314 O_RDWR | O_CREAT, 0644); 11315 Os.chmod(file.getAbsolutePath(), 0644); 11316 return new ParcelFileDescriptor(fd); 11317 } catch (ErrnoException e) { 11318 throw new RemoteException("Failed to open: " + e.getMessage()); 11319 } 11320 } 11321 }; 11322 11323 int ret = PackageManager.INSTALL_SUCCEEDED; 11324 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 11325 if (ret != PackageManager.INSTALL_SUCCEEDED) { 11326 Slog.e(TAG, "Failed to copy package"); 11327 return ret; 11328 } 11329 11330 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 11331 NativeLibraryHelper.Handle handle = null; 11332 try { 11333 handle = NativeLibraryHelper.Handle.create(codeFile); 11334 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 11335 abiOverride); 11336 } catch (IOException e) { 11337 Slog.e(TAG, "Copying native libraries failed", e); 11338 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11339 } finally { 11340 IoUtils.closeQuietly(handle); 11341 } 11342 11343 return ret; 11344 } 11345 doPreInstall(int status)11346 int doPreInstall(int status) { 11347 if (status != PackageManager.INSTALL_SUCCEEDED) { 11348 cleanUp(); 11349 } 11350 return status; 11351 } 11352 doRename(int status, PackageParser.Package pkg, String oldCodePath)11353 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11354 if (status != PackageManager.INSTALL_SUCCEEDED) { 11355 cleanUp(); 11356 return false; 11357 } 11358 11359 final File targetDir = codeFile.getParentFile(); 11360 final File beforeCodeFile = codeFile; 11361 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 11362 11363 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 11364 try { 11365 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 11366 } catch (ErrnoException e) { 11367 Slog.w(TAG, "Failed to rename", e); 11368 return false; 11369 } 11370 11371 if (!SELinux.restoreconRecursive(afterCodeFile)) { 11372 Slog.w(TAG, "Failed to restorecon"); 11373 return false; 11374 } 11375 11376 // Reflect the rename internally 11377 codeFile = afterCodeFile; 11378 resourceFile = afterCodeFile; 11379 11380 // Reflect the rename in scanned details 11381 pkg.codePath = afterCodeFile.getAbsolutePath(); 11382 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11383 pkg.baseCodePath); 11384 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11385 pkg.splitCodePaths); 11386 11387 // Reflect the rename in app info 11388 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11389 pkg.applicationInfo.setCodePath(pkg.codePath); 11390 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11391 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11392 pkg.applicationInfo.setResourcePath(pkg.codePath); 11393 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11394 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11395 11396 return true; 11397 } 11398 doPostInstall(int status, int uid)11399 int doPostInstall(int status, int uid) { 11400 if (status != PackageManager.INSTALL_SUCCEEDED) { 11401 cleanUp(); 11402 } 11403 return status; 11404 } 11405 11406 @Override getCodePath()11407 String getCodePath() { 11408 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 11409 } 11410 11411 @Override getResourcePath()11412 String getResourcePath() { 11413 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 11414 } 11415 cleanUp()11416 private boolean cleanUp() { 11417 if (codeFile == null || !codeFile.exists()) { 11418 return false; 11419 } 11420 11421 if (codeFile.isDirectory()) { 11422 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 11423 } else { 11424 codeFile.delete(); 11425 } 11426 11427 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 11428 resourceFile.delete(); 11429 } 11430 11431 return true; 11432 } 11433 cleanUpResourcesLI()11434 void cleanUpResourcesLI() { 11435 // Try enumerating all code paths before deleting 11436 List<String> allCodePaths = Collections.EMPTY_LIST; 11437 if (codeFile != null && codeFile.exists()) { 11438 try { 11439 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 11440 allCodePaths = pkg.getAllCodePaths(); 11441 } catch (PackageParserException e) { 11442 // Ignored; we tried our best 11443 } 11444 } 11445 11446 cleanUp(); 11447 removeDexFiles(allCodePaths, instructionSets); 11448 } 11449 doPostDeleteLI(boolean delete)11450 boolean doPostDeleteLI(boolean delete) { 11451 // XXX err, shouldn't we respect the delete flag? 11452 cleanUpResourcesLI(); 11453 return true; 11454 } 11455 } 11456 isAsecExternal(String cid)11457 private boolean isAsecExternal(String cid) { 11458 final String asecPath = PackageHelper.getSdFilesystem(cid); 11459 return !asecPath.startsWith(mAsecInternalPath); 11460 } 11461 maybeThrowExceptionForMultiArchCopy(String message, int copyRet)11462 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 11463 PackageManagerException { 11464 if (copyRet < 0) { 11465 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 11466 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 11467 throw new PackageManagerException(copyRet, message); 11468 } 11469 } 11470 } 11471 11472 /** 11473 * Extract the MountService "container ID" from the full code path of an 11474 * .apk. 11475 */ cidFromCodePath(String fullCodePath)11476 static String cidFromCodePath(String fullCodePath) { 11477 int eidx = fullCodePath.lastIndexOf("/"); 11478 String subStr1 = fullCodePath.substring(0, eidx); 11479 int sidx = subStr1.lastIndexOf("/"); 11480 return subStr1.substring(sidx+1, eidx); 11481 } 11482 11483 /** 11484 * Logic to handle installation of ASEC applications, including copying and 11485 * renaming logic. 11486 */ 11487 class AsecInstallArgs extends InstallArgs { 11488 static final String RES_FILE_NAME = "pkg.apk"; 11489 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 11490 11491 String cid; 11492 String packagePath; 11493 String resourcePath; 11494 11495 /** New install */ AsecInstallArgs(InstallParams params)11496 AsecInstallArgs(InstallParams params) { 11497 super(params.origin, params.move, params.observer, params.installFlags, 11498 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11499 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11500 params.grantedRuntimePermissions); 11501 } 11502 11503 /** Existing install */ AsecInstallArgs(String fullCodePath, String[] instructionSets, boolean isExternal, boolean isForwardLocked)11504 AsecInstallArgs(String fullCodePath, String[] instructionSets, 11505 boolean isExternal, boolean isForwardLocked) { 11506 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 11507 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 11508 instructionSets, null, null); 11509 // Hackily pretend we're still looking at a full code path 11510 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 11511 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 11512 } 11513 11514 // Extract cid from fullCodePath 11515 int eidx = fullCodePath.lastIndexOf("/"); 11516 String subStr1 = fullCodePath.substring(0, eidx); 11517 int sidx = subStr1.lastIndexOf("/"); 11518 cid = subStr1.substring(sidx+1, eidx); 11519 setMountPath(subStr1); 11520 } 11521 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked)11522 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 11523 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 11524 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 11525 instructionSets, null, null); 11526 this.cid = cid; 11527 setMountPath(PackageHelper.getSdDir(cid)); 11528 } 11529 createCopyFile()11530 void createCopyFile() { 11531 cid = mInstallerService.allocateExternalStageCidLegacy(); 11532 } 11533 copyApk(IMediaContainerService imcs, boolean temp)11534 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 11535 if (origin.staged) { 11536 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 11537 cid = origin.cid; 11538 setMountPath(PackageHelper.getSdDir(cid)); 11539 return PackageManager.INSTALL_SUCCEEDED; 11540 } 11541 11542 if (temp) { 11543 createCopyFile(); 11544 } else { 11545 /* 11546 * Pre-emptively destroy the container since it's destroyed if 11547 * copying fails due to it existing anyway. 11548 */ 11549 PackageHelper.destroySdDir(cid); 11550 } 11551 11552 final String newMountPath = imcs.copyPackageToContainer( 11553 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 11554 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 11555 11556 if (newMountPath != null) { 11557 setMountPath(newMountPath); 11558 return PackageManager.INSTALL_SUCCEEDED; 11559 } else { 11560 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11561 } 11562 } 11563 11564 @Override getCodePath()11565 String getCodePath() { 11566 return packagePath; 11567 } 11568 11569 @Override getResourcePath()11570 String getResourcePath() { 11571 return resourcePath; 11572 } 11573 doPreInstall(int status)11574 int doPreInstall(int status) { 11575 if (status != PackageManager.INSTALL_SUCCEEDED) { 11576 // Destroy container 11577 PackageHelper.destroySdDir(cid); 11578 } else { 11579 boolean mounted = PackageHelper.isContainerMounted(cid); 11580 if (!mounted) { 11581 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 11582 Process.SYSTEM_UID); 11583 if (newMountPath != null) { 11584 setMountPath(newMountPath); 11585 } else { 11586 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11587 } 11588 } 11589 } 11590 return status; 11591 } 11592 doRename(int status, PackageParser.Package pkg, String oldCodePath)11593 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11594 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 11595 String newMountPath = null; 11596 if (PackageHelper.isContainerMounted(cid)) { 11597 // Unmount the container 11598 if (!PackageHelper.unMountSdDir(cid)) { 11599 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 11600 return false; 11601 } 11602 } 11603 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 11604 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 11605 " which might be stale. Will try to clean up."); 11606 // Clean up the stale container and proceed to recreate. 11607 if (!PackageHelper.destroySdDir(newCacheId)) { 11608 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 11609 return false; 11610 } 11611 // Successfully cleaned up stale container. Try to rename again. 11612 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 11613 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 11614 + " inspite of cleaning it up."); 11615 return false; 11616 } 11617 } 11618 if (!PackageHelper.isContainerMounted(newCacheId)) { 11619 Slog.w(TAG, "Mounting container " + newCacheId); 11620 newMountPath = PackageHelper.mountSdDir(newCacheId, 11621 getEncryptKey(), Process.SYSTEM_UID); 11622 } else { 11623 newMountPath = PackageHelper.getSdDir(newCacheId); 11624 } 11625 if (newMountPath == null) { 11626 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 11627 return false; 11628 } 11629 Log.i(TAG, "Succesfully renamed " + cid + 11630 " to " + newCacheId + 11631 " at new path: " + newMountPath); 11632 cid = newCacheId; 11633 11634 final File beforeCodeFile = new File(packagePath); 11635 setMountPath(newMountPath); 11636 final File afterCodeFile = new File(packagePath); 11637 11638 // Reflect the rename in scanned details 11639 pkg.codePath = afterCodeFile.getAbsolutePath(); 11640 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11641 pkg.baseCodePath); 11642 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 11643 pkg.splitCodePaths); 11644 11645 // Reflect the rename in app info 11646 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11647 pkg.applicationInfo.setCodePath(pkg.codePath); 11648 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11649 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11650 pkg.applicationInfo.setResourcePath(pkg.codePath); 11651 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11652 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11653 11654 return true; 11655 } 11656 setMountPath(String mountPath)11657 private void setMountPath(String mountPath) { 11658 final File mountFile = new File(mountPath); 11659 11660 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 11661 if (monolithicFile.exists()) { 11662 packagePath = monolithicFile.getAbsolutePath(); 11663 if (isFwdLocked()) { 11664 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 11665 } else { 11666 resourcePath = packagePath; 11667 } 11668 } else { 11669 packagePath = mountFile.getAbsolutePath(); 11670 resourcePath = packagePath; 11671 } 11672 } 11673 doPostInstall(int status, int uid)11674 int doPostInstall(int status, int uid) { 11675 if (status != PackageManager.INSTALL_SUCCEEDED) { 11676 cleanUp(); 11677 } else { 11678 final int groupOwner; 11679 final String protectedFile; 11680 if (isFwdLocked()) { 11681 groupOwner = UserHandle.getSharedAppGid(uid); 11682 protectedFile = RES_FILE_NAME; 11683 } else { 11684 groupOwner = -1; 11685 protectedFile = null; 11686 } 11687 11688 if (uid < Process.FIRST_APPLICATION_UID 11689 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 11690 Slog.e(TAG, "Failed to finalize " + cid); 11691 PackageHelper.destroySdDir(cid); 11692 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11693 } 11694 11695 boolean mounted = PackageHelper.isContainerMounted(cid); 11696 if (!mounted) { 11697 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 11698 } 11699 } 11700 return status; 11701 } 11702 cleanUp()11703 private void cleanUp() { 11704 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 11705 11706 // Destroy secure container 11707 PackageHelper.destroySdDir(cid); 11708 } 11709 getAllCodePaths()11710 private List<String> getAllCodePaths() { 11711 final File codeFile = new File(getCodePath()); 11712 if (codeFile != null && codeFile.exists()) { 11713 try { 11714 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 11715 return pkg.getAllCodePaths(); 11716 } catch (PackageParserException e) { 11717 // Ignored; we tried our best 11718 } 11719 } 11720 return Collections.EMPTY_LIST; 11721 } 11722 cleanUpResourcesLI()11723 void cleanUpResourcesLI() { 11724 // Enumerate all code paths before deleting 11725 cleanUpResourcesLI(getAllCodePaths()); 11726 } 11727 cleanUpResourcesLI(List<String> allCodePaths)11728 private void cleanUpResourcesLI(List<String> allCodePaths) { 11729 cleanUp(); 11730 removeDexFiles(allCodePaths, instructionSets); 11731 } 11732 getPackageName()11733 String getPackageName() { 11734 return getAsecPackageName(cid); 11735 } 11736 doPostDeleteLI(boolean delete)11737 boolean doPostDeleteLI(boolean delete) { 11738 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 11739 final List<String> allCodePaths = getAllCodePaths(); 11740 boolean mounted = PackageHelper.isContainerMounted(cid); 11741 if (mounted) { 11742 // Unmount first 11743 if (PackageHelper.unMountSdDir(cid)) { 11744 mounted = false; 11745 } 11746 } 11747 if (!mounted && delete) { 11748 cleanUpResourcesLI(allCodePaths); 11749 } 11750 return !mounted; 11751 } 11752 11753 @Override doPreCopy()11754 int doPreCopy() { 11755 if (isFwdLocked()) { 11756 if (!PackageHelper.fixSdPermissions(cid, 11757 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 11758 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11759 } 11760 } 11761 11762 return PackageManager.INSTALL_SUCCEEDED; 11763 } 11764 11765 @Override doPostCopy(int uid)11766 int doPostCopy(int uid) { 11767 if (isFwdLocked()) { 11768 if (uid < Process.FIRST_APPLICATION_UID 11769 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 11770 RES_FILE_NAME)) { 11771 Slog.e(TAG, "Failed to finalize " + cid); 11772 PackageHelper.destroySdDir(cid); 11773 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11774 } 11775 } 11776 11777 return PackageManager.INSTALL_SUCCEEDED; 11778 } 11779 } 11780 11781 /** 11782 * Logic to handle movement of existing installed applications. 11783 */ 11784 class MoveInstallArgs extends InstallArgs { 11785 private File codeFile; 11786 private File resourceFile; 11787 11788 /** New install */ MoveInstallArgs(InstallParams params)11789 MoveInstallArgs(InstallParams params) { 11790 super(params.origin, params.move, params.observer, params.installFlags, 11791 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 11792 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 11793 params.grantedRuntimePermissions); 11794 } 11795 copyApk(IMediaContainerService imcs, boolean temp)11796 int copyApk(IMediaContainerService imcs, boolean temp) { 11797 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 11798 + move.fromUuid + " to " + move.toUuid); 11799 synchronized (mInstaller) { 11800 if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName, 11801 move.dataAppName, move.appId, move.seinfo) != 0) { 11802 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11803 } 11804 } 11805 11806 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 11807 resourceFile = codeFile; 11808 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 11809 11810 return PackageManager.INSTALL_SUCCEEDED; 11811 } 11812 doPreInstall(int status)11813 int doPreInstall(int status) { 11814 if (status != PackageManager.INSTALL_SUCCEEDED) { 11815 cleanUp(move.toUuid); 11816 } 11817 return status; 11818 } 11819 doRename(int status, PackageParser.Package pkg, String oldCodePath)11820 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 11821 if (status != PackageManager.INSTALL_SUCCEEDED) { 11822 cleanUp(move.toUuid); 11823 return false; 11824 } 11825 11826 // Reflect the move in app info 11827 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 11828 pkg.applicationInfo.setCodePath(pkg.codePath); 11829 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 11830 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 11831 pkg.applicationInfo.setResourcePath(pkg.codePath); 11832 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 11833 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 11834 11835 return true; 11836 } 11837 doPostInstall(int status, int uid)11838 int doPostInstall(int status, int uid) { 11839 if (status == PackageManager.INSTALL_SUCCEEDED) { 11840 cleanUp(move.fromUuid); 11841 } else { 11842 cleanUp(move.toUuid); 11843 } 11844 return status; 11845 } 11846 11847 @Override getCodePath()11848 String getCodePath() { 11849 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 11850 } 11851 11852 @Override getResourcePath()11853 String getResourcePath() { 11854 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 11855 } 11856 cleanUp(String volumeUuid)11857 private boolean cleanUp(String volumeUuid) { 11858 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 11859 move.dataAppName); 11860 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 11861 synchronized (mInstallLock) { 11862 // Clean up both app data and code 11863 removeDataDirsLI(volumeUuid, move.packageName); 11864 if (codeFile.isDirectory()) { 11865 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 11866 } else { 11867 codeFile.delete(); 11868 } 11869 } 11870 return true; 11871 } 11872 cleanUpResourcesLI()11873 void cleanUpResourcesLI() { 11874 throw new UnsupportedOperationException(); 11875 } 11876 doPostDeleteLI(boolean delete)11877 boolean doPostDeleteLI(boolean delete) { 11878 throw new UnsupportedOperationException(); 11879 } 11880 } 11881 getAsecPackageName(String packageCid)11882 static String getAsecPackageName(String packageCid) { 11883 int idx = packageCid.lastIndexOf("-"); 11884 if (idx == -1) { 11885 return packageCid; 11886 } 11887 return packageCid.substring(0, idx); 11888 } 11889 11890 // Utility method used to create code paths based on package name and available index. getNextCodePath(String oldCodePath, String prefix, String suffix)11891 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 11892 String idxStr = ""; 11893 int idx = 1; 11894 // Fall back to default value of idx=1 if prefix is not 11895 // part of oldCodePath 11896 if (oldCodePath != null) { 11897 String subStr = oldCodePath; 11898 // Drop the suffix right away 11899 if (suffix != null && subStr.endsWith(suffix)) { 11900 subStr = subStr.substring(0, subStr.length() - suffix.length()); 11901 } 11902 // If oldCodePath already contains prefix find out the 11903 // ending index to either increment or decrement. 11904 int sidx = subStr.lastIndexOf(prefix); 11905 if (sidx != -1) { 11906 subStr = subStr.substring(sidx + prefix.length()); 11907 if (subStr != null) { 11908 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 11909 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 11910 } 11911 try { 11912 idx = Integer.parseInt(subStr); 11913 if (idx <= 1) { 11914 idx++; 11915 } else { 11916 idx--; 11917 } 11918 } catch(NumberFormatException e) { 11919 } 11920 } 11921 } 11922 } 11923 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 11924 return prefix + idxStr; 11925 } 11926 getNextCodePath(File targetDir, String packageName)11927 private File getNextCodePath(File targetDir, String packageName) { 11928 int suffix = 1; 11929 File result; 11930 do { 11931 result = new File(targetDir, packageName + "-" + suffix); 11932 suffix++; 11933 } while (result.exists()); 11934 return result; 11935 } 11936 11937 // Utility method that returns the relative package path with respect 11938 // to the installation directory. Like say for /data/data/com.test-1.apk 11939 // string com.test-1 is returned. deriveCodePathName(String codePath)11940 static String deriveCodePathName(String codePath) { 11941 if (codePath == null) { 11942 return null; 11943 } 11944 final File codeFile = new File(codePath); 11945 final String name = codeFile.getName(); 11946 if (codeFile.isDirectory()) { 11947 return name; 11948 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 11949 final int lastDot = name.lastIndexOf('.'); 11950 return name.substring(0, lastDot); 11951 } else { 11952 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 11953 return null; 11954 } 11955 } 11956 11957 class PackageInstalledInfo { 11958 String name; 11959 int uid; 11960 // The set of users that originally had this package installed. 11961 int[] origUsers; 11962 // The set of users that now have this package installed. 11963 int[] newUsers; 11964 PackageParser.Package pkg; 11965 int returnCode; 11966 String returnMsg; 11967 PackageRemovedInfo removedInfo; 11968 setError(int code, String msg)11969 public void setError(int code, String msg) { 11970 returnCode = code; 11971 returnMsg = msg; 11972 Slog.w(TAG, msg); 11973 } 11974 setError(String msg, PackageParserException e)11975 public void setError(String msg, PackageParserException e) { 11976 returnCode = e.error; 11977 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11978 Slog.w(TAG, msg, e); 11979 } 11980 setError(String msg, PackageManagerException e)11981 public void setError(String msg, PackageManagerException e) { 11982 returnCode = e.error; 11983 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11984 Slog.w(TAG, msg, e); 11985 } 11986 11987 // In some error cases we want to convey more info back to the observer 11988 String origPackage; 11989 String origPermission; 11990 } 11991 11992 /* 11993 * Install a non-existing package. 11994 */ installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, PackageInstalledInfo res)11995 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 11996 UserHandle user, String installerPackageName, String volumeUuid, 11997 PackageInstalledInfo res) { 11998 // Remember this for later, in case we need to rollback this install 11999 String pkgName = pkg.packageName; 12000 12001 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 12002 final boolean dataDirExists = Environment 12003 .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_OWNER, pkgName).exists(); 12004 synchronized(mPackages) { 12005 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 12006 // A package with the same name is already installed, though 12007 // it has been renamed to an older name. The package we 12008 // are trying to install should be installed as an update to 12009 // the existing one, but that has not been requested, so bail. 12010 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 12011 + " without first uninstalling package running as " 12012 + mSettings.mRenamedPackages.get(pkgName)); 12013 return; 12014 } 12015 if (mPackages.containsKey(pkgName)) { 12016 // Don't allow installation over an existing package with the same name. 12017 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 12018 + " without first uninstalling."); 12019 return; 12020 } 12021 } 12022 12023 try { 12024 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 12025 System.currentTimeMillis(), user); 12026 12027 updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user); 12028 // delete the partially installed application. the data directory will have to be 12029 // restored if it was already existing 12030 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12031 // remove package from internal structures. Note that we want deletePackageX to 12032 // delete the package data and cache directories that it created in 12033 // scanPackageLocked, unless those directories existed before we even tried to 12034 // install. 12035 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 12036 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 12037 res.removedInfo, true); 12038 } 12039 12040 } catch (PackageManagerException e) { 12041 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12042 } 12043 } 12044 shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags)12045 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 12046 // Can't rotate keys during boot or if sharedUser. 12047 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 12048 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 12049 return false; 12050 } 12051 // app is using upgradeKeySets; make sure all are valid 12052 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12053 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 12054 for (int i = 0; i < upgradeKeySets.length; i++) { 12055 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 12056 Slog.wtf(TAG, "Package " 12057 + (oldPs.name != null ? oldPs.name : "<null>") 12058 + " contains upgrade-key-set reference to unknown key-set: " 12059 + upgradeKeySets[i] 12060 + " reverting to signatures check."); 12061 return false; 12062 } 12063 } 12064 return true; 12065 } 12066 checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)12067 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 12068 // Upgrade keysets are being used. Determine if new package has a superset of the 12069 // required keys. 12070 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 12071 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12072 for (int i = 0; i < upgradeKeySets.length; i++) { 12073 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 12074 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 12075 return true; 12076 } 12077 } 12078 return false; 12079 } 12080 replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, PackageInstalledInfo res)12081 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 12082 UserHandle user, String installerPackageName, String volumeUuid, 12083 PackageInstalledInfo res) { 12084 final PackageParser.Package oldPackage; 12085 final String pkgName = pkg.packageName; 12086 final int[] allUsers; 12087 final boolean[] perUserInstalled; 12088 12089 // First find the old package info and check signatures 12090 synchronized(mPackages) { 12091 oldPackage = mPackages.get(pkgName); 12092 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 12093 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12094 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 12095 if(!checkUpgradeKeySetLP(ps, pkg)) { 12096 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 12097 "New package not signed by keys specified by upgrade-keysets: " 12098 + pkgName); 12099 return; 12100 } 12101 } else { 12102 // default to original signature matching 12103 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 12104 != PackageManager.SIGNATURE_MATCH) { 12105 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 12106 "New package has a different signature: " + pkgName); 12107 return; 12108 } 12109 } 12110 12111 // In case of rollback, remember per-user/profile install state 12112 allUsers = sUserManager.getUserIds(); 12113 perUserInstalled = new boolean[allUsers.length]; 12114 for (int i = 0; i < allUsers.length; i++) { 12115 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 12116 } 12117 } 12118 12119 boolean sysPkg = (isSystemApp(oldPackage)); 12120 if (sysPkg) { 12121 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 12122 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 12123 } else { 12124 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 12125 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 12126 } 12127 } 12128 replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, String volumeUuid, PackageInstalledInfo res)12129 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 12130 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 12131 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 12132 String volumeUuid, PackageInstalledInfo res) { 12133 String pkgName = deletedPackage.packageName; 12134 boolean deletedPkg = true; 12135 boolean updatedSettings = false; 12136 12137 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 12138 + deletedPackage); 12139 long origUpdateTime; 12140 if (pkg.mExtras != null) { 12141 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 12142 } else { 12143 origUpdateTime = 0; 12144 } 12145 12146 // First delete the existing package while retaining the data directory 12147 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 12148 res.removedInfo, true)) { 12149 // If the existing package wasn't successfully deleted 12150 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 12151 deletedPkg = false; 12152 } else { 12153 // Successfully deleted the old package; proceed with replace. 12154 12155 // If deleted package lived in a container, give users a chance to 12156 // relinquish resources before killing. 12157 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 12158 if (DEBUG_INSTALL) { 12159 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 12160 } 12161 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 12162 final ArrayList<String> pkgList = new ArrayList<String>(1); 12163 pkgList.add(deletedPackage.applicationInfo.packageName); 12164 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 12165 } 12166 12167 deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName); 12168 try { 12169 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, 12170 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 12171 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 12172 perUserInstalled, res, user); 12173 updatedSettings = true; 12174 } catch (PackageManagerException e) { 12175 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12176 } 12177 } 12178 12179 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12180 // remove package from internal structures. Note that we want deletePackageX to 12181 // delete the package data and cache directories that it created in 12182 // scanPackageLocked, unless those directories existed before we even tried to 12183 // install. 12184 if(updatedSettings) { 12185 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 12186 deletePackageLI( 12187 pkgName, null, true, allUsers, perUserInstalled, 12188 PackageManager.DELETE_KEEP_DATA, 12189 res.removedInfo, true); 12190 } 12191 // Since we failed to install the new package we need to restore the old 12192 // package that we deleted. 12193 if (deletedPkg) { 12194 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 12195 File restoreFile = new File(deletedPackage.codePath); 12196 // Parse old package 12197 boolean oldExternal = isExternal(deletedPackage); 12198 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 12199 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 12200 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 12201 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 12202 try { 12203 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null); 12204 } catch (PackageManagerException e) { 12205 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 12206 + e.getMessage()); 12207 return; 12208 } 12209 // Restore of old package succeeded. Update permissions. 12210 // writer 12211 synchronized (mPackages) { 12212 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 12213 UPDATE_PERMISSIONS_ALL); 12214 // can downgrade to reader 12215 mSettings.writeLPr(); 12216 } 12217 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 12218 } 12219 } 12220 } 12221 replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, String volumeUuid, PackageInstalledInfo res)12222 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 12223 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 12224 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 12225 String volumeUuid, PackageInstalledInfo res) { 12226 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 12227 + ", old=" + deletedPackage); 12228 boolean disabledSystem = false; 12229 boolean updatedSettings = false; 12230 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 12231 if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 12232 != 0) { 12233 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 12234 } 12235 String packageName = deletedPackage.packageName; 12236 if (packageName == null) { 12237 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 12238 "Attempt to delete null packageName."); 12239 return; 12240 } 12241 PackageParser.Package oldPkg; 12242 PackageSetting oldPkgSetting; 12243 // reader 12244 synchronized (mPackages) { 12245 oldPkg = mPackages.get(packageName); 12246 oldPkgSetting = mSettings.mPackages.get(packageName); 12247 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 12248 (oldPkgSetting == null)) { 12249 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 12250 "Couldn't find package:" + packageName + " information"); 12251 return; 12252 } 12253 } 12254 12255 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 12256 12257 res.removedInfo.uid = oldPkg.applicationInfo.uid; 12258 res.removedInfo.removedPackage = packageName; 12259 // Remove existing system package 12260 removePackageLI(oldPkgSetting, true); 12261 // writer 12262 synchronized (mPackages) { 12263 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 12264 if (!disabledSystem && deletedPackage != null) { 12265 // We didn't need to disable the .apk as a current system package, 12266 // which means we are replacing another update that is already 12267 // installed. We need to make sure to delete the older one's .apk. 12268 res.removedInfo.args = createInstallArgsForExisting(0, 12269 deletedPackage.applicationInfo.getCodePath(), 12270 deletedPackage.applicationInfo.getResourcePath(), 12271 getAppDexInstructionSets(deletedPackage.applicationInfo)); 12272 } else { 12273 res.removedInfo.args = null; 12274 } 12275 } 12276 12277 // Successfully disabled the old package. Now proceed with re-installation 12278 deleteCodeCacheDirsLI(pkg.volumeUuid, packageName); 12279 12280 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12281 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 12282 12283 PackageParser.Package newPackage = null; 12284 try { 12285 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user); 12286 if (newPackage.mExtras != null) { 12287 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 12288 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 12289 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 12290 12291 // is the update attempting to change shared user? that isn't going to work... 12292 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 12293 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 12294 "Forbidding shared user change from " + oldPkgSetting.sharedUser 12295 + " to " + newPkgSetting.sharedUser); 12296 updatedSettings = true; 12297 } 12298 } 12299 12300 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12301 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 12302 perUserInstalled, res, user); 12303 updatedSettings = true; 12304 } 12305 12306 } catch (PackageManagerException e) { 12307 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12308 } 12309 12310 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12311 // Re installation failed. Restore old information 12312 // Remove new pkg information 12313 if (newPackage != null) { 12314 removeInstalledPackageLI(newPackage, true); 12315 } 12316 // Add back the old system package 12317 try { 12318 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 12319 } catch (PackageManagerException e) { 12320 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 12321 } 12322 // Restore the old system information in Settings 12323 synchronized (mPackages) { 12324 if (disabledSystem) { 12325 mSettings.enableSystemPackageLPw(packageName); 12326 } 12327 if (updatedSettings) { 12328 mSettings.setInstallerPackageName(packageName, 12329 oldPkgSetting.installerPackageName); 12330 } 12331 mSettings.writeLPr(); 12332 } 12333 } 12334 } 12335 revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds)12336 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 12337 // Collect all used permissions in the UID 12338 ArraySet<String> usedPermissions = new ArraySet<>(); 12339 final int packageCount = su.packages.size(); 12340 for (int i = 0; i < packageCount; i++) { 12341 PackageSetting ps = su.packages.valueAt(i); 12342 if (ps.pkg == null) { 12343 continue; 12344 } 12345 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 12346 for (int j = 0; j < requestedPermCount; j++) { 12347 String permission = ps.pkg.requestedPermissions.get(j); 12348 BasePermission bp = mSettings.mPermissions.get(permission); 12349 if (bp != null) { 12350 usedPermissions.add(permission); 12351 } 12352 } 12353 } 12354 12355 PermissionsState permissionsState = su.getPermissionsState(); 12356 // Prune install permissions 12357 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 12358 final int installPermCount = installPermStates.size(); 12359 for (int i = installPermCount - 1; i >= 0; i--) { 12360 PermissionState permissionState = installPermStates.get(i); 12361 if (!usedPermissions.contains(permissionState.getName())) { 12362 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 12363 if (bp != null) { 12364 permissionsState.revokeInstallPermission(bp); 12365 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 12366 PackageManager.MASK_PERMISSION_FLAGS, 0); 12367 } 12368 } 12369 } 12370 12371 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 12372 12373 // Prune runtime permissions 12374 for (int userId : allUserIds) { 12375 List<PermissionState> runtimePermStates = permissionsState 12376 .getRuntimePermissionStates(userId); 12377 final int runtimePermCount = runtimePermStates.size(); 12378 for (int i = runtimePermCount - 1; i >= 0; i--) { 12379 PermissionState permissionState = runtimePermStates.get(i); 12380 if (!usedPermissions.contains(permissionState.getName())) { 12381 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 12382 if (bp != null) { 12383 permissionsState.revokeRuntimePermission(bp, userId); 12384 permissionsState.updatePermissionFlags(bp, userId, 12385 PackageManager.MASK_PERMISSION_FLAGS, 0); 12386 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 12387 runtimePermissionChangedUserIds, userId); 12388 } 12389 } 12390 } 12391 } 12392 12393 return runtimePermissionChangedUserIds; 12394 } 12395 updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, UserHandle user)12396 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 12397 String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, 12398 UserHandle user) { 12399 String pkgName = newPackage.packageName; 12400 synchronized (mPackages) { 12401 //write settings. the installStatus will be incomplete at this stage. 12402 //note that the new package setting would have already been 12403 //added to mPackages. It hasn't been persisted yet. 12404 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 12405 mSettings.writeLPr(); 12406 } 12407 12408 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 12409 12410 synchronized (mPackages) { 12411 updatePermissionsLPw(newPackage.packageName, newPackage, 12412 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 12413 ? UPDATE_PERMISSIONS_ALL : 0)); 12414 // For system-bundled packages, we assume that installing an upgraded version 12415 // of the package implies that the user actually wants to run that new code, 12416 // so we enable the package. 12417 PackageSetting ps = mSettings.mPackages.get(pkgName); 12418 if (ps != null) { 12419 if (isSystemApp(newPackage)) { 12420 // NB: implicit assumption that system package upgrades apply to all users 12421 if (DEBUG_INSTALL) { 12422 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 12423 } 12424 if (res.origUsers != null) { 12425 for (int userHandle : res.origUsers) { 12426 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 12427 userHandle, installerPackageName); 12428 } 12429 } 12430 // Also convey the prior install/uninstall state 12431 if (allUsers != null && perUserInstalled != null) { 12432 for (int i = 0; i < allUsers.length; i++) { 12433 if (DEBUG_INSTALL) { 12434 Slog.d(TAG, " user " + allUsers[i] 12435 + " => " + perUserInstalled[i]); 12436 } 12437 ps.setInstalled(perUserInstalled[i], allUsers[i]); 12438 } 12439 // these install state changes will be persisted in the 12440 // upcoming call to mSettings.writeLPr(). 12441 } 12442 } 12443 // It's implied that when a user requests installation, they want the app to be 12444 // installed and enabled. 12445 int userId = user.getIdentifier(); 12446 if (userId != UserHandle.USER_ALL) { 12447 ps.setInstalled(true, userId); 12448 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 12449 } 12450 } 12451 res.name = pkgName; 12452 res.uid = newPackage.applicationInfo.uid; 12453 res.pkg = newPackage; 12454 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 12455 mSettings.setInstallerPackageName(pkgName, installerPackageName); 12456 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12457 //to update install status 12458 mSettings.writeLPr(); 12459 } 12460 } 12461 installPackageLI(InstallArgs args, PackageInstalledInfo res)12462 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 12463 final int installFlags = args.installFlags; 12464 final String installerPackageName = args.installerPackageName; 12465 final String volumeUuid = args.volumeUuid; 12466 final File tmpPackageFile = new File(args.getCodePath()); 12467 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 12468 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 12469 || (args.volumeUuid != null)); 12470 boolean replace = false; 12471 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 12472 if (args.move != null) { 12473 // moving a complete application; perfom an initial scan on the new install location 12474 scanFlags |= SCAN_INITIAL; 12475 } 12476 // Result object to be returned 12477 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 12478 12479 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 12480 // Retrieve PackageSettings and parse package 12481 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 12482 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 12483 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 12484 PackageParser pp = new PackageParser(); 12485 pp.setSeparateProcesses(mSeparateProcesses); 12486 pp.setDisplayMetrics(mMetrics); 12487 12488 final PackageParser.Package pkg; 12489 try { 12490 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 12491 } catch (PackageParserException e) { 12492 res.setError("Failed parse during installPackageLI", e); 12493 return; 12494 } 12495 12496 // Mark that we have an install time CPU ABI override. 12497 pkg.cpuAbiOverride = args.abiOverride; 12498 12499 String pkgName = res.name = pkg.packageName; 12500 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 12501 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 12502 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 12503 return; 12504 } 12505 } 12506 12507 try { 12508 pp.collectCertificates(pkg, parseFlags); 12509 pp.collectManifestDigest(pkg); 12510 } catch (PackageParserException e) { 12511 res.setError("Failed collect during installPackageLI", e); 12512 return; 12513 } 12514 12515 /* If the installer passed in a manifest digest, compare it now. */ 12516 if (args.manifestDigest != null) { 12517 if (DEBUG_INSTALL) { 12518 final String parsedManifest = pkg.manifestDigest == null ? "null" 12519 : pkg.manifestDigest.toString(); 12520 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 12521 + parsedManifest); 12522 } 12523 12524 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 12525 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 12526 return; 12527 } 12528 } else if (DEBUG_INSTALL) { 12529 final String parsedManifest = pkg.manifestDigest == null 12530 ? "null" : pkg.manifestDigest.toString(); 12531 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 12532 } 12533 12534 // Get rid of all references to package scan path via parser. 12535 pp = null; 12536 String oldCodePath = null; 12537 boolean systemApp = false; 12538 synchronized (mPackages) { 12539 // Check if installing already existing package 12540 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12541 String oldName = mSettings.mRenamedPackages.get(pkgName); 12542 if (pkg.mOriginalPackages != null 12543 && pkg.mOriginalPackages.contains(oldName) 12544 && mPackages.containsKey(oldName)) { 12545 // This package is derived from an original package, 12546 // and this device has been updating from that original 12547 // name. We must continue using the original name, so 12548 // rename the new package here. 12549 pkg.setPackageName(oldName); 12550 pkgName = pkg.packageName; 12551 replace = true; 12552 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 12553 + oldName + " pkgName=" + pkgName); 12554 } else if (mPackages.containsKey(pkgName)) { 12555 // This package, under its official name, already exists 12556 // on the device; we should replace it. 12557 replace = true; 12558 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 12559 } 12560 12561 // Prevent apps opting out from runtime permissions 12562 if (replace) { 12563 PackageParser.Package oldPackage = mPackages.get(pkgName); 12564 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 12565 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 12566 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 12567 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 12568 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 12569 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 12570 + " doesn't support runtime permissions but the old" 12571 + " target SDK " + oldTargetSdk + " does."); 12572 return; 12573 } 12574 } 12575 } 12576 12577 PackageSetting ps = mSettings.mPackages.get(pkgName); 12578 if (ps != null) { 12579 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 12580 12581 // Quick sanity check that we're signed correctly if updating; 12582 // we'll check this again later when scanning, but we want to 12583 // bail early here before tripping over redefined permissions. 12584 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 12585 if (!checkUpgradeKeySetLP(ps, pkg)) { 12586 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 12587 + pkg.packageName + " upgrade keys do not match the " 12588 + "previously installed version"); 12589 return; 12590 } 12591 } else { 12592 try { 12593 verifySignaturesLP(ps, pkg); 12594 } catch (PackageManagerException e) { 12595 res.setError(e.error, e.getMessage()); 12596 return; 12597 } 12598 } 12599 12600 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 12601 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 12602 systemApp = (ps.pkg.applicationInfo.flags & 12603 ApplicationInfo.FLAG_SYSTEM) != 0; 12604 } 12605 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 12606 } 12607 12608 // Check whether the newly-scanned package wants to define an already-defined perm 12609 int N = pkg.permissions.size(); 12610 for (int i = N-1; i >= 0; i--) { 12611 PackageParser.Permission perm = pkg.permissions.get(i); 12612 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 12613 if (bp != null) { 12614 // If the defining package is signed with our cert, it's okay. This 12615 // also includes the "updating the same package" case, of course. 12616 // "updating same package" could also involve key-rotation. 12617 final boolean sigsOk; 12618 if (bp.sourcePackage.equals(pkg.packageName) 12619 && (bp.packageSetting instanceof PackageSetting) 12620 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 12621 scanFlags))) { 12622 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 12623 } else { 12624 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 12625 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 12626 } 12627 if (!sigsOk) { 12628 // If the owning package is the system itself, we log but allow 12629 // install to proceed; we fail the install on all other permission 12630 // redefinitions. 12631 if (!bp.sourcePackage.equals("android")) { 12632 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 12633 + pkg.packageName + " attempting to redeclare permission " 12634 + perm.info.name + " already owned by " + bp.sourcePackage); 12635 res.origPermission = perm.info.name; 12636 res.origPackage = bp.sourcePackage; 12637 return; 12638 } else { 12639 Slog.w(TAG, "Package " + pkg.packageName 12640 + " attempting to redeclare system permission " 12641 + perm.info.name + "; ignoring new declaration"); 12642 pkg.permissions.remove(i); 12643 } 12644 } 12645 } 12646 } 12647 12648 } 12649 12650 if (systemApp && onExternal) { 12651 // Disable updates to system apps on sdcard 12652 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 12653 "Cannot install updates to system apps on sdcard"); 12654 return; 12655 } 12656 12657 if (args.move != null) { 12658 // We did an in-place move, so dex is ready to roll 12659 scanFlags |= SCAN_NO_DEX; 12660 scanFlags |= SCAN_MOVE; 12661 12662 synchronized (mPackages) { 12663 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12664 if (ps == null) { 12665 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 12666 "Missing settings for moved package " + pkgName); 12667 } 12668 12669 // We moved the entire application as-is, so bring over the 12670 // previously derived ABI information. 12671 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 12672 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 12673 } 12674 12675 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 12676 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 12677 scanFlags |= SCAN_NO_DEX; 12678 12679 try { 12680 derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride, 12681 true /* extract libs */); 12682 } catch (PackageManagerException pme) { 12683 Slog.e(TAG, "Error deriving application ABI", pme); 12684 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 12685 return; 12686 } 12687 12688 // Run dexopt before old package gets removed, to minimize time when app is unavailable 12689 int result = mPackageDexOptimizer 12690 .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */, 12691 false /* defer */, false /* inclDependencies */, 12692 true /* boot complete */); 12693 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 12694 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); 12695 return; 12696 } 12697 } 12698 12699 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 12700 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 12701 return; 12702 } 12703 12704 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 12705 12706 if (replace) { 12707 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 12708 installerPackageName, volumeUuid, res); 12709 } else { 12710 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 12711 args.user, installerPackageName, volumeUuid, res); 12712 } 12713 synchronized (mPackages) { 12714 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12715 if (ps != null) { 12716 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 12717 } 12718 } 12719 } 12720 startIntentFilterVerifications(int userId, boolean replacing, PackageParser.Package pkg)12721 private void startIntentFilterVerifications(int userId, boolean replacing, 12722 PackageParser.Package pkg) { 12723 if (mIntentFilterVerifierComponent == null) { 12724 Slog.w(TAG, "No IntentFilter verification will not be done as " 12725 + "there is no IntentFilterVerifier available!"); 12726 return; 12727 } 12728 12729 final int verifierUid = getPackageUid( 12730 mIntentFilterVerifierComponent.getPackageName(), 12731 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId); 12732 12733 mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); 12734 final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 12735 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 12736 mHandler.sendMessage(msg); 12737 } 12738 verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, PackageParser.Package pkg)12739 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 12740 PackageParser.Package pkg) { 12741 int size = pkg.activities.size(); 12742 if (size == 0) { 12743 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12744 "No activity, so no need to verify any IntentFilter!"); 12745 return; 12746 } 12747 12748 final boolean hasDomainURLs = hasDomainURLs(pkg); 12749 if (!hasDomainURLs) { 12750 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12751 "No domain URLs, so no need to verify any IntentFilter!"); 12752 return; 12753 } 12754 12755 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 12756 + " if any IntentFilter from the " + size 12757 + " Activities needs verification ..."); 12758 12759 int count = 0; 12760 final String packageName = pkg.packageName; 12761 12762 synchronized (mPackages) { 12763 // If this is a new install and we see that we've already run verification for this 12764 // package, we have nothing to do: it means the state was restored from backup. 12765 if (!replacing) { 12766 IntentFilterVerificationInfo ivi = 12767 mSettings.getIntentFilterVerificationLPr(packageName); 12768 if (ivi != null) { 12769 if (DEBUG_DOMAIN_VERIFICATION) { 12770 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 12771 + ivi.getStatusString()); 12772 } 12773 return; 12774 } 12775 } 12776 12777 // If any filters need to be verified, then all need to be. 12778 boolean needToVerify = false; 12779 for (PackageParser.Activity a : pkg.activities) { 12780 for (ActivityIntentInfo filter : a.intents) { 12781 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 12782 if (DEBUG_DOMAIN_VERIFICATION) { 12783 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 12784 } 12785 needToVerify = true; 12786 break; 12787 } 12788 } 12789 } 12790 12791 if (needToVerify) { 12792 final int verificationId = mIntentFilterVerificationToken++; 12793 for (PackageParser.Activity a : pkg.activities) { 12794 for (ActivityIntentInfo filter : a.intents) { 12795 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 12796 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 12797 "Verification needed for IntentFilter:" + filter.toString()); 12798 mIntentFilterVerifier.addOneIntentFilterVerification( 12799 verifierUid, userId, verificationId, filter, packageName); 12800 count++; 12801 } 12802 } 12803 } 12804 } 12805 } 12806 12807 if (count > 0) { 12808 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 12809 + " IntentFilter verification" + (count > 1 ? "s" : "") 12810 + " for userId:" + userId); 12811 mIntentFilterVerifier.startVerifications(userId); 12812 } else { 12813 if (DEBUG_DOMAIN_VERIFICATION) { 12814 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 12815 } 12816 } 12817 } 12818 needsNetworkVerificationLPr(ActivityIntentInfo filter)12819 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 12820 final ComponentName cn = filter.activity.getComponentName(); 12821 final String packageName = cn.getPackageName(); 12822 12823 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 12824 packageName); 12825 if (ivi == null) { 12826 return true; 12827 } 12828 int status = ivi.getStatus(); 12829 switch (status) { 12830 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 12831 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 12832 return true; 12833 12834 default: 12835 // Nothing to do 12836 return false; 12837 } 12838 } 12839 isMultiArch(PackageSetting ps)12840 private static boolean isMultiArch(PackageSetting ps) { 12841 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 12842 } 12843 isMultiArch(ApplicationInfo info)12844 private static boolean isMultiArch(ApplicationInfo info) { 12845 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 12846 } 12847 isExternal(PackageParser.Package pkg)12848 private static boolean isExternal(PackageParser.Package pkg) { 12849 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12850 } 12851 isExternal(PackageSetting ps)12852 private static boolean isExternal(PackageSetting ps) { 12853 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12854 } 12855 isExternal(ApplicationInfo info)12856 private static boolean isExternal(ApplicationInfo info) { 12857 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 12858 } 12859 isSystemApp(PackageParser.Package pkg)12860 private static boolean isSystemApp(PackageParser.Package pkg) { 12861 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12862 } 12863 isPrivilegedApp(PackageParser.Package pkg)12864 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 12865 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 12866 } 12867 hasDomainURLs(PackageParser.Package pkg)12868 private static boolean hasDomainURLs(PackageParser.Package pkg) { 12869 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 12870 } 12871 isSystemApp(PackageSetting ps)12872 private static boolean isSystemApp(PackageSetting ps) { 12873 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 12874 } 12875 isUpdatedSystemApp(PackageSetting ps)12876 private static boolean isUpdatedSystemApp(PackageSetting ps) { 12877 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 12878 } 12879 packageFlagsToInstallFlags(PackageSetting ps)12880 private int packageFlagsToInstallFlags(PackageSetting ps) { 12881 int installFlags = 0; 12882 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 12883 // This existing package was an external ASEC install when we have 12884 // the external flag without a UUID 12885 installFlags |= PackageManager.INSTALL_EXTERNAL; 12886 } 12887 if (ps.isForwardLocked()) { 12888 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 12889 } 12890 return installFlags; 12891 } 12892 getVolumeUuidForPackage(PackageParser.Package pkg)12893 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 12894 if (isExternal(pkg)) { 12895 if (TextUtils.isEmpty(pkg.volumeUuid)) { 12896 return StorageManager.UUID_PRIMARY_PHYSICAL; 12897 } else { 12898 return pkg.volumeUuid; 12899 } 12900 } else { 12901 return StorageManager.UUID_PRIVATE_INTERNAL; 12902 } 12903 } 12904 getSettingsVersionForPackage(PackageParser.Package pkg)12905 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 12906 if (isExternal(pkg)) { 12907 if (TextUtils.isEmpty(pkg.volumeUuid)) { 12908 return mSettings.getExternalVersion(); 12909 } else { 12910 return mSettings.findOrCreateVersion(pkg.volumeUuid); 12911 } 12912 } else { 12913 return mSettings.getInternalVersion(); 12914 } 12915 } 12916 deleteTempPackageFiles()12917 private void deleteTempPackageFiles() { 12918 final FilenameFilter filter = new FilenameFilter() { 12919 public boolean accept(File dir, String name) { 12920 return name.startsWith("vmdl") && name.endsWith(".tmp"); 12921 } 12922 }; 12923 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 12924 file.delete(); 12925 } 12926 } 12927 12928 @Override deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, int flags)12929 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 12930 int flags) { 12931 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 12932 flags); 12933 } 12934 12935 @Override deletePackage(final String packageName, final IPackageDeleteObserver2 observer, final int userId, final int flags)12936 public void deletePackage(final String packageName, 12937 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 12938 mContext.enforceCallingOrSelfPermission( 12939 android.Manifest.permission.DELETE_PACKAGES, null); 12940 Preconditions.checkNotNull(packageName); 12941 Preconditions.checkNotNull(observer); 12942 final int uid = Binder.getCallingUid(); 12943 if (UserHandle.getUserId(uid) != userId) { 12944 mContext.enforceCallingPermission( 12945 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12946 "deletePackage for user " + userId); 12947 } 12948 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 12949 try { 12950 observer.onPackageDeleted(packageName, 12951 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 12952 } catch (RemoteException re) { 12953 } 12954 return; 12955 } 12956 12957 boolean uninstallBlocked = false; 12958 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 12959 int[] users = sUserManager.getUserIds(); 12960 for (int i = 0; i < users.length; ++i) { 12961 if (getBlockUninstallForUser(packageName, users[i])) { 12962 uninstallBlocked = true; 12963 break; 12964 } 12965 } 12966 } else { 12967 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 12968 } 12969 if (uninstallBlocked) { 12970 try { 12971 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 12972 null); 12973 } catch (RemoteException re) { 12974 } 12975 return; 12976 } 12977 12978 if (DEBUG_REMOVE) { 12979 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 12980 } 12981 // Queue up an async operation since the package deletion may take a little while. 12982 mHandler.post(new Runnable() { 12983 public void run() { 12984 mHandler.removeCallbacks(this); 12985 final int returnCode = deletePackageX(packageName, userId, flags); 12986 if (observer != null) { 12987 try { 12988 observer.onPackageDeleted(packageName, returnCode, null); 12989 } catch (RemoteException e) { 12990 Log.i(TAG, "Observer no longer exists."); 12991 } //end catch 12992 } //end if 12993 } //end run 12994 }); 12995 } 12996 isPackageDeviceAdmin(String packageName, int userId)12997 private boolean isPackageDeviceAdmin(String packageName, int userId) { 12998 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 12999 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 13000 try { 13001 if (dpm != null) { 13002 if (dpm.isDeviceOwner(packageName)) { 13003 return true; 13004 } 13005 int[] users; 13006 if (userId == UserHandle.USER_ALL) { 13007 users = sUserManager.getUserIds(); 13008 } else { 13009 users = new int[]{userId}; 13010 } 13011 for (int i = 0; i < users.length; ++i) { 13012 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 13013 return true; 13014 } 13015 } 13016 } 13017 } catch (RemoteException e) { 13018 } 13019 return false; 13020 } 13021 13022 /** 13023 * This method is an internal method that could be get invoked either 13024 * to delete an installed package or to clean up a failed installation. 13025 * After deleting an installed package, a broadcast is sent to notify any 13026 * listeners that the package has been installed. For cleaning up a failed 13027 * installation, the broadcast is not necessary since the package's 13028 * installation wouldn't have sent the initial broadcast either 13029 * The key steps in deleting a package are 13030 * deleting the package information in internal structures like mPackages, 13031 * deleting the packages base directories through installd 13032 * updating mSettings to reflect current status 13033 * persisting settings for later use 13034 * sending a broadcast if necessary 13035 */ deletePackageX(String packageName, int userId, int flags)13036 private int deletePackageX(String packageName, int userId, int flags) { 13037 final PackageRemovedInfo info = new PackageRemovedInfo(); 13038 final boolean res; 13039 13040 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 13041 ? UserHandle.ALL : new UserHandle(userId); 13042 13043 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 13044 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 13045 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 13046 } 13047 13048 boolean removedForAllUsers = false; 13049 boolean systemUpdate = false; 13050 13051 // for the uninstall-updates case and restricted profiles, remember the per- 13052 // userhandle installed state 13053 int[] allUsers; 13054 boolean[] perUserInstalled; 13055 synchronized (mPackages) { 13056 PackageSetting ps = mSettings.mPackages.get(packageName); 13057 allUsers = sUserManager.getUserIds(); 13058 perUserInstalled = new boolean[allUsers.length]; 13059 for (int i = 0; i < allUsers.length; i++) { 13060 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 13061 } 13062 } 13063 13064 synchronized (mInstallLock) { 13065 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 13066 res = deletePackageLI(packageName, removeForUser, 13067 true, allUsers, perUserInstalled, 13068 flags | REMOVE_CHATTY, info, true); 13069 systemUpdate = info.isRemovedPackageSystemUpdate; 13070 if (res && !systemUpdate && mPackages.get(packageName) == null) { 13071 removedForAllUsers = true; 13072 } 13073 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 13074 + " removedForAllUsers=" + removedForAllUsers); 13075 } 13076 13077 if (res) { 13078 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 13079 13080 // If the removed package was a system update, the old system package 13081 // was re-enabled; we need to broadcast this information 13082 if (systemUpdate) { 13083 Bundle extras = new Bundle(1); 13084 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 13085 ? info.removedAppId : info.uid); 13086 extras.putBoolean(Intent.EXTRA_REPLACING, true); 13087 13088 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 13089 extras, null, null, null); 13090 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 13091 extras, null, null, null); 13092 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 13093 null, packageName, null, null); 13094 } 13095 } 13096 // Force a gc here. 13097 Runtime.getRuntime().gc(); 13098 // Delete the resources here after sending the broadcast to let 13099 // other processes clean up before deleting resources. 13100 if (info.args != null) { 13101 synchronized (mInstallLock) { 13102 info.args.doPostDeleteLI(true); 13103 } 13104 } 13105 13106 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 13107 } 13108 13109 class PackageRemovedInfo { 13110 String removedPackage; 13111 int uid = -1; 13112 int removedAppId = -1; 13113 int[] removedUsers = null; 13114 boolean isRemovedPackageSystemUpdate = false; 13115 // Clean up resources deleted packages. 13116 InstallArgs args = null; 13117 sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers)13118 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 13119 Bundle extras = new Bundle(1); 13120 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 13121 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 13122 if (replacing) { 13123 extras.putBoolean(Intent.EXTRA_REPLACING, true); 13124 } 13125 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 13126 if (removedPackage != null) { 13127 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 13128 extras, null, null, removedUsers); 13129 if (fullRemove && !replacing) { 13130 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 13131 extras, null, null, removedUsers); 13132 } 13133 } 13134 if (removedAppId >= 0) { 13135 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 13136 removedUsers); 13137 } 13138 } 13139 } 13140 13141 /* 13142 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 13143 * flag is not set, the data directory is removed as well. 13144 * make sure this flag is set for partially installed apps. If not its meaningless to 13145 * delete a partially installed application. 13146 */ removePackageDataLI(PackageSetting ps, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, int flags, boolean writeSettings)13147 private void removePackageDataLI(PackageSetting ps, 13148 int[] allUserHandles, boolean[] perUserInstalled, 13149 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 13150 String packageName = ps.name; 13151 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 13152 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 13153 // Retrieve object to delete permissions for shared user later on 13154 final PackageSetting deletedPs; 13155 // reader 13156 synchronized (mPackages) { 13157 deletedPs = mSettings.mPackages.get(packageName); 13158 if (outInfo != null) { 13159 outInfo.removedPackage = packageName; 13160 outInfo.removedUsers = deletedPs != null 13161 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 13162 : null; 13163 } 13164 } 13165 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 13166 removeDataDirsLI(ps.volumeUuid, packageName); 13167 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 13168 } 13169 // writer 13170 synchronized (mPackages) { 13171 if (deletedPs != null) { 13172 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 13173 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 13174 clearDefaultBrowserIfNeeded(packageName); 13175 if (outInfo != null) { 13176 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 13177 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 13178 } 13179 updatePermissionsLPw(deletedPs.name, null, 0); 13180 if (deletedPs.sharedUser != null) { 13181 // Remove permissions associated with package. Since runtime 13182 // permissions are per user we have to kill the removed package 13183 // or packages running under the shared user of the removed 13184 // package if revoking the permissions requested only by the removed 13185 // package is successful and this causes a change in gids. 13186 for (int userId : UserManagerService.getInstance().getUserIds()) { 13187 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 13188 userId); 13189 if (userIdToKill == UserHandle.USER_ALL 13190 || userIdToKill >= UserHandle.USER_OWNER) { 13191 // If gids changed for this user, kill all affected packages. 13192 mHandler.post(new Runnable() { 13193 @Override 13194 public void run() { 13195 // This has to happen with no lock held. 13196 killApplication(deletedPs.name, deletedPs.appId, 13197 KILL_APP_REASON_GIDS_CHANGED); 13198 } 13199 }); 13200 break; 13201 } 13202 } 13203 } 13204 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 13205 } 13206 // make sure to preserve per-user disabled state if this removal was just 13207 // a downgrade of a system app to the factory package 13208 if (allUserHandles != null && perUserInstalled != null) { 13209 if (DEBUG_REMOVE) { 13210 Slog.d(TAG, "Propagating install state across downgrade"); 13211 } 13212 for (int i = 0; i < allUserHandles.length; i++) { 13213 if (DEBUG_REMOVE) { 13214 Slog.d(TAG, " user " + allUserHandles[i] 13215 + " => " + perUserInstalled[i]); 13216 } 13217 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 13218 } 13219 } 13220 } 13221 // can downgrade to reader 13222 if (writeSettings) { 13223 // Save settings now 13224 mSettings.writeLPr(); 13225 } 13226 } 13227 if (outInfo != null) { 13228 // A user ID was deleted here. Go through all users and remove it 13229 // from KeyStore. 13230 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 13231 } 13232 } 13233 locationIsPrivileged(File path)13234 static boolean locationIsPrivileged(File path) { 13235 try { 13236 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 13237 .getCanonicalPath(); 13238 return path.getCanonicalPath().startsWith(privilegedAppDir); 13239 } catch (IOException e) { 13240 Slog.e(TAG, "Unable to access code path " + path); 13241 } 13242 return false; 13243 } 13244 13245 /* 13246 * Tries to delete system package. 13247 */ deleteSystemPackageLI(PackageSetting newPs, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)13248 private boolean deleteSystemPackageLI(PackageSetting newPs, 13249 int[] allUserHandles, boolean[] perUserInstalled, 13250 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 13251 final boolean applyUserRestrictions 13252 = (allUserHandles != null) && (perUserInstalled != null); 13253 PackageSetting disabledPs = null; 13254 // Confirm if the system package has been updated 13255 // An updated system app can be deleted. This will also have to restore 13256 // the system pkg from system partition 13257 // reader 13258 synchronized (mPackages) { 13259 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 13260 } 13261 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 13262 + " disabledPs=" + disabledPs); 13263 if (disabledPs == null) { 13264 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 13265 return false; 13266 } else if (DEBUG_REMOVE) { 13267 Slog.d(TAG, "Deleting system pkg from data partition"); 13268 } 13269 if (DEBUG_REMOVE) { 13270 if (applyUserRestrictions) { 13271 Slog.d(TAG, "Remembering install states:"); 13272 for (int i = 0; i < allUserHandles.length; i++) { 13273 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 13274 } 13275 } 13276 } 13277 // Delete the updated package 13278 outInfo.isRemovedPackageSystemUpdate = true; 13279 if (disabledPs.versionCode < newPs.versionCode) { 13280 // Delete data for downgrades 13281 flags &= ~PackageManager.DELETE_KEEP_DATA; 13282 } else { 13283 // Preserve data by setting flag 13284 flags |= PackageManager.DELETE_KEEP_DATA; 13285 } 13286 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 13287 allUserHandles, perUserInstalled, outInfo, writeSettings); 13288 if (!ret) { 13289 return false; 13290 } 13291 // writer 13292 synchronized (mPackages) { 13293 // Reinstate the old system package 13294 mSettings.enableSystemPackageLPw(newPs.name); 13295 // Remove any native libraries from the upgraded package. 13296 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 13297 } 13298 // Install the system package 13299 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 13300 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 13301 if (locationIsPrivileged(disabledPs.codePath)) { 13302 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13303 } 13304 13305 final PackageParser.Package newPkg; 13306 try { 13307 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 13308 } catch (PackageManagerException e) { 13309 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 13310 return false; 13311 } 13312 13313 // writer 13314 synchronized (mPackages) { 13315 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 13316 13317 // Propagate the permissions state as we do not want to drop on the floor 13318 // runtime permissions. The update permissions method below will take 13319 // care of removing obsolete permissions and grant install permissions. 13320 ps.getPermissionsState().copyFrom(newPs.getPermissionsState()); 13321 updatePermissionsLPw(newPkg.packageName, newPkg, 13322 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 13323 13324 if (applyUserRestrictions) { 13325 if (DEBUG_REMOVE) { 13326 Slog.d(TAG, "Propagating install state across reinstall"); 13327 } 13328 for (int i = 0; i < allUserHandles.length; i++) { 13329 if (DEBUG_REMOVE) { 13330 Slog.d(TAG, " user " + allUserHandles[i] 13331 + " => " + perUserInstalled[i]); 13332 } 13333 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 13334 13335 mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false); 13336 } 13337 // Regardless of writeSettings we need to ensure that this restriction 13338 // state propagation is persisted 13339 mSettings.writeAllUsersPackageRestrictionsLPr(); 13340 } 13341 // can downgrade to reader here 13342 if (writeSettings) { 13343 mSettings.writeLPr(); 13344 } 13345 } 13346 return true; 13347 } 13348 deleteInstalledPackageLI(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, boolean writeSettings)13349 private boolean deleteInstalledPackageLI(PackageSetting ps, 13350 boolean deleteCodeAndResources, int flags, 13351 int[] allUserHandles, boolean[] perUserInstalled, 13352 PackageRemovedInfo outInfo, boolean writeSettings) { 13353 if (outInfo != null) { 13354 outInfo.uid = ps.appId; 13355 } 13356 13357 // Delete package data from internal structures and also remove data if flag is set 13358 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 13359 13360 // Delete application code and resources 13361 if (deleteCodeAndResources && (outInfo != null)) { 13362 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 13363 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 13364 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 13365 } 13366 return true; 13367 } 13368 13369 @Override setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)13370 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 13371 int userId) { 13372 mContext.enforceCallingOrSelfPermission( 13373 android.Manifest.permission.DELETE_PACKAGES, null); 13374 synchronized (mPackages) { 13375 PackageSetting ps = mSettings.mPackages.get(packageName); 13376 if (ps == null) { 13377 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 13378 return false; 13379 } 13380 if (!ps.getInstalled(userId)) { 13381 // Can't block uninstall for an app that is not installed or enabled. 13382 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 13383 return false; 13384 } 13385 ps.setBlockUninstall(blockUninstall, userId); 13386 mSettings.writePackageRestrictionsLPr(userId); 13387 } 13388 return true; 13389 } 13390 13391 @Override getBlockUninstallForUser(String packageName, int userId)13392 public boolean getBlockUninstallForUser(String packageName, int userId) { 13393 synchronized (mPackages) { 13394 PackageSetting ps = mSettings.mPackages.get(packageName); 13395 if (ps == null) { 13396 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 13397 return false; 13398 } 13399 return ps.getBlockUninstall(userId); 13400 } 13401 } 13402 13403 /* 13404 * This method handles package deletion in general 13405 */ deletePackageLI(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)13406 private boolean deletePackageLI(String packageName, UserHandle user, 13407 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 13408 int flags, PackageRemovedInfo outInfo, 13409 boolean writeSettings) { 13410 if (packageName == null) { 13411 Slog.w(TAG, "Attempt to delete null packageName."); 13412 return false; 13413 } 13414 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 13415 PackageSetting ps; 13416 boolean dataOnly = false; 13417 int removeUser = -1; 13418 int appId = -1; 13419 synchronized (mPackages) { 13420 ps = mSettings.mPackages.get(packageName); 13421 if (ps == null) { 13422 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 13423 return false; 13424 } 13425 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 13426 && user.getIdentifier() != UserHandle.USER_ALL) { 13427 // The caller is asking that the package only be deleted for a single 13428 // user. To do this, we just mark its uninstalled state and delete 13429 // its data. If this is a system app, we only allow this to happen if 13430 // they have set the special DELETE_SYSTEM_APP which requests different 13431 // semantics than normal for uninstalling system apps. 13432 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 13433 final int userId = user.getIdentifier(); 13434 ps.setUserState(userId, 13435 COMPONENT_ENABLED_STATE_DEFAULT, 13436 false, //installed 13437 true, //stopped 13438 true, //notLaunched 13439 false, //hidden 13440 null, null, null, 13441 false, // blockUninstall 13442 ps.readUserState(userId).domainVerificationStatus, 0); 13443 if (!isSystemApp(ps)) { 13444 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 13445 // Other user still have this package installed, so all 13446 // we need to do is clear this user's data and save that 13447 // it is uninstalled. 13448 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 13449 removeUser = user.getIdentifier(); 13450 appId = ps.appId; 13451 scheduleWritePackageRestrictionsLocked(removeUser); 13452 } else { 13453 // We need to set it back to 'installed' so the uninstall 13454 // broadcasts will be sent correctly. 13455 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 13456 ps.setInstalled(true, user.getIdentifier()); 13457 } 13458 } else { 13459 // This is a system app, so we assume that the 13460 // other users still have this package installed, so all 13461 // we need to do is clear this user's data and save that 13462 // it is uninstalled. 13463 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 13464 removeUser = user.getIdentifier(); 13465 appId = ps.appId; 13466 scheduleWritePackageRestrictionsLocked(removeUser); 13467 } 13468 } 13469 } 13470 13471 if (removeUser >= 0) { 13472 // From above, we determined that we are deleting this only 13473 // for a single user. Continue the work here. 13474 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 13475 if (outInfo != null) { 13476 outInfo.removedPackage = packageName; 13477 outInfo.removedAppId = appId; 13478 outInfo.removedUsers = new int[] {removeUser}; 13479 } 13480 mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser); 13481 removeKeystoreDataIfNeeded(removeUser, appId); 13482 schedulePackageCleaning(packageName, removeUser, false); 13483 synchronized (mPackages) { 13484 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { 13485 scheduleWritePackageRestrictionsLocked(removeUser); 13486 } 13487 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser); 13488 } 13489 return true; 13490 } 13491 13492 if (dataOnly) { 13493 // Delete application data first 13494 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 13495 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 13496 return true; 13497 } 13498 13499 boolean ret = false; 13500 if (isSystemApp(ps)) { 13501 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 13502 // When an updated system application is deleted we delete the existing resources as well and 13503 // fall back to existing code in system partition 13504 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 13505 flags, outInfo, writeSettings); 13506 } else { 13507 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 13508 // Kill application pre-emptively especially for apps on sd. 13509 killApplication(packageName, ps.appId, "uninstall pkg"); 13510 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 13511 allUserHandles, perUserInstalled, 13512 outInfo, writeSettings); 13513 } 13514 13515 return ret; 13516 } 13517 13518 private final class ClearStorageConnection implements ServiceConnection { 13519 IMediaContainerService mContainerService; 13520 13521 @Override onServiceConnected(ComponentName name, IBinder service)13522 public void onServiceConnected(ComponentName name, IBinder service) { 13523 synchronized (this) { 13524 mContainerService = IMediaContainerService.Stub.asInterface(service); 13525 notifyAll(); 13526 } 13527 } 13528 13529 @Override onServiceDisconnected(ComponentName name)13530 public void onServiceDisconnected(ComponentName name) { 13531 } 13532 } 13533 clearExternalStorageDataSync(String packageName, int userId, boolean allData)13534 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 13535 final boolean mounted; 13536 if (Environment.isExternalStorageEmulated()) { 13537 mounted = true; 13538 } else { 13539 final String status = Environment.getExternalStorageState(); 13540 13541 mounted = status.equals(Environment.MEDIA_MOUNTED) 13542 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 13543 } 13544 13545 if (!mounted) { 13546 return; 13547 } 13548 13549 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 13550 int[] users; 13551 if (userId == UserHandle.USER_ALL) { 13552 users = sUserManager.getUserIds(); 13553 } else { 13554 users = new int[] { userId }; 13555 } 13556 final ClearStorageConnection conn = new ClearStorageConnection(); 13557 if (mContext.bindServiceAsUser( 13558 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 13559 try { 13560 for (int curUser : users) { 13561 long timeout = SystemClock.uptimeMillis() + 5000; 13562 synchronized (conn) { 13563 long now = SystemClock.uptimeMillis(); 13564 while (conn.mContainerService == null && now < timeout) { 13565 try { 13566 conn.wait(timeout - now); 13567 } catch (InterruptedException e) { 13568 } 13569 } 13570 } 13571 if (conn.mContainerService == null) { 13572 return; 13573 } 13574 13575 final UserEnvironment userEnv = new UserEnvironment(curUser); 13576 clearDirectory(conn.mContainerService, 13577 userEnv.buildExternalStorageAppCacheDirs(packageName)); 13578 if (allData) { 13579 clearDirectory(conn.mContainerService, 13580 userEnv.buildExternalStorageAppDataDirs(packageName)); 13581 clearDirectory(conn.mContainerService, 13582 userEnv.buildExternalStorageAppMediaDirs(packageName)); 13583 } 13584 } 13585 } finally { 13586 mContext.unbindService(conn); 13587 } 13588 } 13589 } 13590 13591 @Override clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)13592 public void clearApplicationUserData(final String packageName, 13593 final IPackageDataObserver observer, final int userId) { 13594 mContext.enforceCallingOrSelfPermission( 13595 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 13596 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 13597 // Queue up an async operation since the package deletion may take a little while. 13598 mHandler.post(new Runnable() { 13599 public void run() { 13600 mHandler.removeCallbacks(this); 13601 final boolean succeeded; 13602 synchronized (mInstallLock) { 13603 succeeded = clearApplicationUserDataLI(packageName, userId); 13604 } 13605 clearExternalStorageDataSync(packageName, userId, true); 13606 if (succeeded) { 13607 // invoke DeviceStorageMonitor's update method to clear any notifications 13608 DeviceStorageMonitorInternal 13609 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 13610 if (dsm != null) { 13611 dsm.checkMemory(); 13612 } 13613 } 13614 if(observer != null) { 13615 try { 13616 observer.onRemoveCompleted(packageName, succeeded); 13617 } catch (RemoteException e) { 13618 Log.i(TAG, "Observer no longer exists."); 13619 } 13620 } //end if observer 13621 } //end run 13622 }); 13623 } 13624 clearApplicationUserDataLI(String packageName, int userId)13625 private boolean clearApplicationUserDataLI(String packageName, int userId) { 13626 if (packageName == null) { 13627 Slog.w(TAG, "Attempt to delete null packageName."); 13628 return false; 13629 } 13630 13631 // Try finding details about the requested package 13632 PackageParser.Package pkg; 13633 synchronized (mPackages) { 13634 pkg = mPackages.get(packageName); 13635 if (pkg == null) { 13636 final PackageSetting ps = mSettings.mPackages.get(packageName); 13637 if (ps != null) { 13638 pkg = ps.pkg; 13639 } 13640 } 13641 13642 if (pkg == null) { 13643 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 13644 return false; 13645 } 13646 13647 PackageSetting ps = (PackageSetting) pkg.mExtras; 13648 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 13649 } 13650 13651 // Always delete data directories for package, even if we found no other 13652 // record of app. This helps users recover from UID mismatches without 13653 // resorting to a full data wipe. 13654 int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId); 13655 if (retCode < 0) { 13656 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 13657 return false; 13658 } 13659 13660 final int appId = pkg.applicationInfo.uid; 13661 removeKeystoreDataIfNeeded(userId, appId); 13662 13663 // Create a native library symlink only if we have native libraries 13664 // and if the native libraries are 32 bit libraries. We do not provide 13665 // this symlink for 64 bit libraries. 13666 if (pkg.applicationInfo.primaryCpuAbi != null && 13667 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 13668 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 13669 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 13670 nativeLibPath, userId) < 0) { 13671 Slog.w(TAG, "Failed linking native library dir"); 13672 return false; 13673 } 13674 } 13675 13676 return true; 13677 } 13678 13679 /** 13680 * Reverts user permission state changes (permissions and flags) in 13681 * all packages for a given user. 13682 * 13683 * @param userId The device user for which to do a reset. 13684 */ resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId)13685 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 13686 final int packageCount = mPackages.size(); 13687 for (int i = 0; i < packageCount; i++) { 13688 PackageParser.Package pkg = mPackages.valueAt(i); 13689 PackageSetting ps = (PackageSetting) pkg.mExtras; 13690 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 13691 } 13692 } 13693 13694 /** 13695 * Reverts user permission state changes (permissions and flags). 13696 * 13697 * @param ps The package for which to reset. 13698 * @param userId The device user for which to do a reset. 13699 */ resetUserChangesToRuntimePermissionsAndFlagsLPw( final PackageSetting ps, final int userId)13700 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 13701 final PackageSetting ps, final int userId) { 13702 if (ps.pkg == null) { 13703 return; 13704 } 13705 13706 final int userSettableFlags = FLAG_PERMISSION_USER_SET 13707 | FLAG_PERMISSION_USER_FIXED 13708 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 13709 13710 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 13711 | FLAG_PERMISSION_POLICY_FIXED; 13712 13713 boolean writeInstallPermissions = false; 13714 boolean writeRuntimePermissions = false; 13715 13716 final int permissionCount = ps.pkg.requestedPermissions.size(); 13717 for (int i = 0; i < permissionCount; i++) { 13718 String permission = ps.pkg.requestedPermissions.get(i); 13719 13720 BasePermission bp = mSettings.mPermissions.get(permission); 13721 if (bp == null) { 13722 continue; 13723 } 13724 13725 // If shared user we just reset the state to which only this app contributed. 13726 if (ps.sharedUser != null) { 13727 boolean used = false; 13728 final int packageCount = ps.sharedUser.packages.size(); 13729 for (int j = 0; j < packageCount; j++) { 13730 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 13731 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 13732 && pkg.pkg.requestedPermissions.contains(permission)) { 13733 used = true; 13734 break; 13735 } 13736 } 13737 if (used) { 13738 continue; 13739 } 13740 } 13741 13742 PermissionsState permissionsState = ps.getPermissionsState(); 13743 13744 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 13745 13746 // Always clear the user settable flags. 13747 final boolean hasInstallState = permissionsState.getInstallPermissionState( 13748 bp.name) != null; 13749 if (permissionsState.updatePermissionFlags(bp, userId, userSettableFlags, 0)) { 13750 if (hasInstallState) { 13751 writeInstallPermissions = true; 13752 } else { 13753 writeRuntimePermissions = true; 13754 } 13755 } 13756 13757 // Below is only runtime permission handling. 13758 if (!bp.isRuntime()) { 13759 continue; 13760 } 13761 13762 // Never clobber system or policy. 13763 if ((oldFlags & policyOrSystemFlags) != 0) { 13764 continue; 13765 } 13766 13767 // If this permission was granted by default, make sure it is. 13768 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 13769 if (permissionsState.grantRuntimePermission(bp, userId) 13770 != PERMISSION_OPERATION_FAILURE) { 13771 writeRuntimePermissions = true; 13772 } 13773 } else { 13774 // Otherwise, reset the permission. 13775 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 13776 switch (revokeResult) { 13777 case PERMISSION_OPERATION_SUCCESS: { 13778 writeRuntimePermissions = true; 13779 } break; 13780 13781 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 13782 writeRuntimePermissions = true; 13783 final int appId = ps.appId; 13784 mHandler.post(new Runnable() { 13785 @Override 13786 public void run() { 13787 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 13788 } 13789 }); 13790 } break; 13791 } 13792 } 13793 } 13794 13795 // Synchronously write as we are taking permissions away. 13796 if (writeRuntimePermissions) { 13797 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 13798 } 13799 13800 // Synchronously write as we are taking permissions away. 13801 if (writeInstallPermissions) { 13802 mSettings.writeLPr(); 13803 } 13804 } 13805 13806 /** 13807 * Remove entries from the keystore daemon. Will only remove it if the 13808 * {@code appId} is valid. 13809 */ removeKeystoreDataIfNeeded(int userId, int appId)13810 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 13811 if (appId < 0) { 13812 return; 13813 } 13814 13815 final KeyStore keyStore = KeyStore.getInstance(); 13816 if (keyStore != null) { 13817 if (userId == UserHandle.USER_ALL) { 13818 for (final int individual : sUserManager.getUserIds()) { 13819 keyStore.clearUid(UserHandle.getUid(individual, appId)); 13820 } 13821 } else { 13822 keyStore.clearUid(UserHandle.getUid(userId, appId)); 13823 } 13824 } else { 13825 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 13826 } 13827 } 13828 13829 @Override deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)13830 public void deleteApplicationCacheFiles(final String packageName, 13831 final IPackageDataObserver observer) { 13832 mContext.enforceCallingOrSelfPermission( 13833 android.Manifest.permission.DELETE_CACHE_FILES, null); 13834 // Queue up an async operation since the package deletion may take a little while. 13835 final int userId = UserHandle.getCallingUserId(); 13836 mHandler.post(new Runnable() { 13837 public void run() { 13838 mHandler.removeCallbacks(this); 13839 final boolean succeded; 13840 synchronized (mInstallLock) { 13841 succeded = deleteApplicationCacheFilesLI(packageName, userId); 13842 } 13843 clearExternalStorageDataSync(packageName, userId, false); 13844 if (observer != null) { 13845 try { 13846 observer.onRemoveCompleted(packageName, succeded); 13847 } catch (RemoteException e) { 13848 Log.i(TAG, "Observer no longer exists."); 13849 } 13850 } //end if observer 13851 } //end run 13852 }); 13853 } 13854 deleteApplicationCacheFilesLI(String packageName, int userId)13855 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 13856 if (packageName == null) { 13857 Slog.w(TAG, "Attempt to delete null packageName."); 13858 return false; 13859 } 13860 PackageParser.Package p; 13861 synchronized (mPackages) { 13862 p = mPackages.get(packageName); 13863 } 13864 if (p == null) { 13865 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 13866 return false; 13867 } 13868 final ApplicationInfo applicationInfo = p.applicationInfo; 13869 if (applicationInfo == null) { 13870 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 13871 return false; 13872 } 13873 int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId); 13874 if (retCode < 0) { 13875 Slog.w(TAG, "Couldn't remove cache files for package: " 13876 + packageName + " u" + userId); 13877 return false; 13878 } 13879 return true; 13880 } 13881 13882 @Override getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)13883 public void getPackageSizeInfo(final String packageName, int userHandle, 13884 final IPackageStatsObserver observer) { 13885 mContext.enforceCallingOrSelfPermission( 13886 android.Manifest.permission.GET_PACKAGE_SIZE, null); 13887 if (packageName == null) { 13888 throw new IllegalArgumentException("Attempt to get size of null packageName"); 13889 } 13890 13891 PackageStats stats = new PackageStats(packageName, userHandle); 13892 13893 /* 13894 * Queue up an async operation since the package measurement may take a 13895 * little while. 13896 */ 13897 Message msg = mHandler.obtainMessage(INIT_COPY); 13898 msg.obj = new MeasureParams(stats, observer); 13899 mHandler.sendMessage(msg); 13900 } 13901 getPackageSizeInfoLI(String packageName, int userHandle, PackageStats pStats)13902 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 13903 PackageStats pStats) { 13904 if (packageName == null) { 13905 Slog.w(TAG, "Attempt to get size of null packageName."); 13906 return false; 13907 } 13908 PackageParser.Package p; 13909 boolean dataOnly = false; 13910 String libDirRoot = null; 13911 String asecPath = null; 13912 PackageSetting ps = null; 13913 synchronized (mPackages) { 13914 p = mPackages.get(packageName); 13915 ps = mSettings.mPackages.get(packageName); 13916 if(p == null) { 13917 dataOnly = true; 13918 if((ps == null) || (ps.pkg == null)) { 13919 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 13920 return false; 13921 } 13922 p = ps.pkg; 13923 } 13924 if (ps != null) { 13925 libDirRoot = ps.legacyNativeLibraryPathString; 13926 } 13927 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 13928 final long token = Binder.clearCallingIdentity(); 13929 try { 13930 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 13931 if (secureContainerId != null) { 13932 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 13933 } 13934 } finally { 13935 Binder.restoreCallingIdentity(token); 13936 } 13937 } 13938 } 13939 String publicSrcDir = null; 13940 if(!dataOnly) { 13941 final ApplicationInfo applicationInfo = p.applicationInfo; 13942 if (applicationInfo == null) { 13943 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 13944 return false; 13945 } 13946 if (p.isForwardLocked()) { 13947 publicSrcDir = applicationInfo.getBaseResourcePath(); 13948 } 13949 } 13950 // TODO: extend to measure size of split APKs 13951 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 13952 // not just the first level. 13953 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 13954 // just the primary. 13955 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 13956 13957 String apkPath; 13958 File packageDir = new File(p.codePath); 13959 13960 if (packageDir.isDirectory() && p.canHaveOatDir()) { 13961 apkPath = packageDir.getAbsolutePath(); 13962 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 13963 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 13964 libDirRoot = null; 13965 } 13966 } else { 13967 apkPath = p.baseCodePath; 13968 } 13969 13970 int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath, 13971 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 13972 if (res < 0) { 13973 return false; 13974 } 13975 13976 // Fix-up for forward-locked applications in ASEC containers. 13977 if (!isExternal(p)) { 13978 pStats.codeSize += pStats.externalCodeSize; 13979 pStats.externalCodeSize = 0L; 13980 } 13981 13982 return true; 13983 } 13984 13985 13986 @Override addPackageToPreferred(String packageName)13987 public void addPackageToPreferred(String packageName) { 13988 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 13989 } 13990 13991 @Override removePackageFromPreferred(String packageName)13992 public void removePackageFromPreferred(String packageName) { 13993 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 13994 } 13995 13996 @Override getPreferredPackages(int flags)13997 public List<PackageInfo> getPreferredPackages(int flags) { 13998 return new ArrayList<PackageInfo>(); 13999 } 14000 getUidTargetSdkVersionLockedLPr(int uid)14001 private int getUidTargetSdkVersionLockedLPr(int uid) { 14002 Object obj = mSettings.getUserIdLPr(uid); 14003 if (obj instanceof SharedUserSetting) { 14004 final SharedUserSetting sus = (SharedUserSetting) obj; 14005 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 14006 final Iterator<PackageSetting> it = sus.packages.iterator(); 14007 while (it.hasNext()) { 14008 final PackageSetting ps = it.next(); 14009 if (ps.pkg != null) { 14010 int v = ps.pkg.applicationInfo.targetSdkVersion; 14011 if (v < vers) vers = v; 14012 } 14013 } 14014 return vers; 14015 } else if (obj instanceof PackageSetting) { 14016 final PackageSetting ps = (PackageSetting) obj; 14017 if (ps.pkg != null) { 14018 return ps.pkg.applicationInfo.targetSdkVersion; 14019 } 14020 } 14021 return Build.VERSION_CODES.CUR_DEVELOPMENT; 14022 } 14023 14024 @Override addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)14025 public void addPreferredActivity(IntentFilter filter, int match, 14026 ComponentName[] set, ComponentName activity, int userId) { 14027 addPreferredActivityInternal(filter, match, set, activity, true, userId, 14028 "Adding preferred"); 14029 } 14030 addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname)14031 private void addPreferredActivityInternal(IntentFilter filter, int match, 14032 ComponentName[] set, ComponentName activity, boolean always, int userId, 14033 String opname) { 14034 // writer 14035 int callingUid = Binder.getCallingUid(); 14036 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 14037 if (filter.countActions() == 0) { 14038 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 14039 return; 14040 } 14041 synchronized (mPackages) { 14042 if (mContext.checkCallingOrSelfPermission( 14043 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 14044 != PackageManager.PERMISSION_GRANTED) { 14045 if (getUidTargetSdkVersionLockedLPr(callingUid) 14046 < Build.VERSION_CODES.FROYO) { 14047 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 14048 + callingUid); 14049 return; 14050 } 14051 mContext.enforceCallingOrSelfPermission( 14052 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14053 } 14054 14055 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 14056 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 14057 + userId + ":"); 14058 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14059 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 14060 scheduleWritePackageRestrictionsLocked(userId); 14061 } 14062 } 14063 14064 @Override replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)14065 public void replacePreferredActivity(IntentFilter filter, int match, 14066 ComponentName[] set, ComponentName activity, int userId) { 14067 if (filter.countActions() != 1) { 14068 throw new IllegalArgumentException( 14069 "replacePreferredActivity expects filter to have only 1 action."); 14070 } 14071 if (filter.countDataAuthorities() != 0 14072 || filter.countDataPaths() != 0 14073 || filter.countDataSchemes() > 1 14074 || filter.countDataTypes() != 0) { 14075 throw new IllegalArgumentException( 14076 "replacePreferredActivity expects filter to have no data authorities, " + 14077 "paths, or types; and at most one scheme."); 14078 } 14079 14080 final int callingUid = Binder.getCallingUid(); 14081 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 14082 synchronized (mPackages) { 14083 if (mContext.checkCallingOrSelfPermission( 14084 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 14085 != PackageManager.PERMISSION_GRANTED) { 14086 if (getUidTargetSdkVersionLockedLPr(callingUid) 14087 < Build.VERSION_CODES.FROYO) { 14088 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 14089 + Binder.getCallingUid()); 14090 return; 14091 } 14092 mContext.enforceCallingOrSelfPermission( 14093 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14094 } 14095 14096 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 14097 if (pir != null) { 14098 // Get all of the existing entries that exactly match this filter. 14099 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 14100 if (existing != null && existing.size() == 1) { 14101 PreferredActivity cur = existing.get(0); 14102 if (DEBUG_PREFERRED) { 14103 Slog.i(TAG, "Checking replace of preferred:"); 14104 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14105 if (!cur.mPref.mAlways) { 14106 Slog.i(TAG, " -- CUR; not mAlways!"); 14107 } else { 14108 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 14109 Slog.i(TAG, " -- CUR: mSet=" 14110 + Arrays.toString(cur.mPref.mSetComponents)); 14111 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 14112 Slog.i(TAG, " -- NEW: mMatch=" 14113 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 14114 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 14115 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 14116 } 14117 } 14118 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 14119 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 14120 && cur.mPref.sameSet(set)) { 14121 // Setting the preferred activity to what it happens to be already 14122 if (DEBUG_PREFERRED) { 14123 Slog.i(TAG, "Replacing with same preferred activity " 14124 + cur.mPref.mShortComponent + " for user " 14125 + userId + ":"); 14126 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14127 } 14128 return; 14129 } 14130 } 14131 14132 if (existing != null) { 14133 if (DEBUG_PREFERRED) { 14134 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 14135 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14136 } 14137 for (int i = 0; i < existing.size(); i++) { 14138 PreferredActivity pa = existing.get(i); 14139 if (DEBUG_PREFERRED) { 14140 Slog.i(TAG, "Removing existing preferred activity " 14141 + pa.mPref.mComponent + ":"); 14142 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 14143 } 14144 pir.removeFilter(pa); 14145 } 14146 } 14147 } 14148 addPreferredActivityInternal(filter, match, set, activity, true, userId, 14149 "Replacing preferred"); 14150 } 14151 } 14152 14153 @Override clearPackagePreferredActivities(String packageName)14154 public void clearPackagePreferredActivities(String packageName) { 14155 final int uid = Binder.getCallingUid(); 14156 // writer 14157 synchronized (mPackages) { 14158 PackageParser.Package pkg = mPackages.get(packageName); 14159 if (pkg == null || pkg.applicationInfo.uid != uid) { 14160 if (mContext.checkCallingOrSelfPermission( 14161 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 14162 != PackageManager.PERMISSION_GRANTED) { 14163 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 14164 < Build.VERSION_CODES.FROYO) { 14165 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 14166 + Binder.getCallingUid()); 14167 return; 14168 } 14169 mContext.enforceCallingOrSelfPermission( 14170 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14171 } 14172 } 14173 14174 int user = UserHandle.getCallingUserId(); 14175 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 14176 scheduleWritePackageRestrictionsLocked(user); 14177 } 14178 } 14179 } 14180 14181 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ clearPackagePreferredActivitiesLPw(String packageName, int userId)14182 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 14183 ArrayList<PreferredActivity> removed = null; 14184 boolean changed = false; 14185 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 14186 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 14187 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 14188 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 14189 continue; 14190 } 14191 Iterator<PreferredActivity> it = pir.filterIterator(); 14192 while (it.hasNext()) { 14193 PreferredActivity pa = it.next(); 14194 // Mark entry for removal only if it matches the package name 14195 // and the entry is of type "always". 14196 if (packageName == null || 14197 (pa.mPref.mComponent.getPackageName().equals(packageName) 14198 && pa.mPref.mAlways)) { 14199 if (removed == null) { 14200 removed = new ArrayList<PreferredActivity>(); 14201 } 14202 removed.add(pa); 14203 } 14204 } 14205 if (removed != null) { 14206 for (int j=0; j<removed.size(); j++) { 14207 PreferredActivity pa = removed.get(j); 14208 pir.removeFilter(pa); 14209 } 14210 changed = true; 14211 } 14212 } 14213 return changed; 14214 } 14215 14216 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ clearIntentFilterVerificationsLPw(int userId)14217 private void clearIntentFilterVerificationsLPw(int userId) { 14218 final int packageCount = mPackages.size(); 14219 for (int i = 0; i < packageCount; i++) { 14220 PackageParser.Package pkg = mPackages.valueAt(i); 14221 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 14222 } 14223 } 14224 14225 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ clearIntentFilterVerificationsLPw(String packageName, int userId)14226 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 14227 if (userId == UserHandle.USER_ALL) { 14228 if (mSettings.removeIntentFilterVerificationLPw(packageName, 14229 sUserManager.getUserIds())) { 14230 for (int oneUserId : sUserManager.getUserIds()) { 14231 scheduleWritePackageRestrictionsLocked(oneUserId); 14232 } 14233 } 14234 } else { 14235 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 14236 scheduleWritePackageRestrictionsLocked(userId); 14237 } 14238 } 14239 } 14240 clearDefaultBrowserIfNeeded(String packageName)14241 void clearDefaultBrowserIfNeeded(String packageName) { 14242 for (int oneUserId : sUserManager.getUserIds()) { 14243 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 14244 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 14245 if (packageName.equals(defaultBrowserPackageName)) { 14246 setDefaultBrowserPackageName(null, oneUserId); 14247 } 14248 } 14249 } 14250 14251 @Override resetApplicationPreferences(int userId)14252 public void resetApplicationPreferences(int userId) { 14253 mContext.enforceCallingOrSelfPermission( 14254 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 14255 // writer 14256 synchronized (mPackages) { 14257 final long identity = Binder.clearCallingIdentity(); 14258 try { 14259 clearPackagePreferredActivitiesLPw(null, userId); 14260 mSettings.applyDefaultPreferredAppsLPw(this, userId); 14261 // TODO: We have to reset the default SMS and Phone. This requires 14262 // significant refactoring to keep all default apps in the package 14263 // manager (cleaner but more work) or have the services provide 14264 // callbacks to the package manager to request a default app reset. 14265 applyFactoryDefaultBrowserLPw(userId); 14266 clearIntentFilterVerificationsLPw(userId); 14267 primeDomainVerificationsLPw(userId); 14268 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 14269 scheduleWritePackageRestrictionsLocked(userId); 14270 } finally { 14271 Binder.restoreCallingIdentity(identity); 14272 } 14273 } 14274 } 14275 14276 @Override getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)14277 public int getPreferredActivities(List<IntentFilter> outFilters, 14278 List<ComponentName> outActivities, String packageName) { 14279 14280 int num = 0; 14281 final int userId = UserHandle.getCallingUserId(); 14282 // reader 14283 synchronized (mPackages) { 14284 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 14285 if (pir != null) { 14286 final Iterator<PreferredActivity> it = pir.filterIterator(); 14287 while (it.hasNext()) { 14288 final PreferredActivity pa = it.next(); 14289 if (packageName == null 14290 || (pa.mPref.mComponent.getPackageName().equals(packageName) 14291 && pa.mPref.mAlways)) { 14292 if (outFilters != null) { 14293 outFilters.add(new IntentFilter(pa)); 14294 } 14295 if (outActivities != null) { 14296 outActivities.add(pa.mPref.mComponent); 14297 } 14298 } 14299 } 14300 } 14301 } 14302 14303 return num; 14304 } 14305 14306 @Override addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)14307 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 14308 int userId) { 14309 int callingUid = Binder.getCallingUid(); 14310 if (callingUid != Process.SYSTEM_UID) { 14311 throw new SecurityException( 14312 "addPersistentPreferredActivity can only be run by the system"); 14313 } 14314 if (filter.countActions() == 0) { 14315 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 14316 return; 14317 } 14318 synchronized (mPackages) { 14319 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 14320 " :"); 14321 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 14322 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 14323 new PersistentPreferredActivity(filter, activity)); 14324 scheduleWritePackageRestrictionsLocked(userId); 14325 } 14326 } 14327 14328 @Override clearPackagePersistentPreferredActivities(String packageName, int userId)14329 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 14330 int callingUid = Binder.getCallingUid(); 14331 if (callingUid != Process.SYSTEM_UID) { 14332 throw new SecurityException( 14333 "clearPackagePersistentPreferredActivities can only be run by the system"); 14334 } 14335 ArrayList<PersistentPreferredActivity> removed = null; 14336 boolean changed = false; 14337 synchronized (mPackages) { 14338 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 14339 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 14340 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 14341 .valueAt(i); 14342 if (userId != thisUserId) { 14343 continue; 14344 } 14345 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 14346 while (it.hasNext()) { 14347 PersistentPreferredActivity ppa = it.next(); 14348 // Mark entry for removal only if it matches the package name. 14349 if (ppa.mComponent.getPackageName().equals(packageName)) { 14350 if (removed == null) { 14351 removed = new ArrayList<PersistentPreferredActivity>(); 14352 } 14353 removed.add(ppa); 14354 } 14355 } 14356 if (removed != null) { 14357 for (int j=0; j<removed.size(); j++) { 14358 PersistentPreferredActivity ppa = removed.get(j); 14359 ppir.removeFilter(ppa); 14360 } 14361 changed = true; 14362 } 14363 } 14364 14365 if (changed) { 14366 scheduleWritePackageRestrictionsLocked(userId); 14367 } 14368 } 14369 } 14370 14371 /** 14372 * Common machinery for picking apart a restored XML blob and passing 14373 * it to a caller-supplied functor to be applied to the running system. 14374 */ restoreFromXml(XmlPullParser parser, int userId, String expectedStartTag, BlobXmlRestorer functor)14375 private void restoreFromXml(XmlPullParser parser, int userId, 14376 String expectedStartTag, BlobXmlRestorer functor) 14377 throws IOException, XmlPullParserException { 14378 int type; 14379 while ((type = parser.next()) != XmlPullParser.START_TAG 14380 && type != XmlPullParser.END_DOCUMENT) { 14381 } 14382 if (type != XmlPullParser.START_TAG) { 14383 // oops didn't find a start tag?! 14384 if (DEBUG_BACKUP) { 14385 Slog.e(TAG, "Didn't find start tag during restore"); 14386 } 14387 return; 14388 } 14389 14390 // this is supposed to be TAG_PREFERRED_BACKUP 14391 if (!expectedStartTag.equals(parser.getName())) { 14392 if (DEBUG_BACKUP) { 14393 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 14394 } 14395 return; 14396 } 14397 14398 // skip interfering stuff, then we're aligned with the backing implementation 14399 while ((type = parser.next()) == XmlPullParser.TEXT) { } 14400 functor.apply(parser, userId); 14401 } 14402 14403 private interface BlobXmlRestorer { apply(XmlPullParser parser, int userId)14404 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 14405 } 14406 14407 /** 14408 * Non-Binder method, support for the backup/restore mechanism: write the 14409 * full set of preferred activities in its canonical XML format. Returns the 14410 * XML output as a byte array, or null if there is none. 14411 */ 14412 @Override getPreferredActivityBackup(int userId)14413 public byte[] getPreferredActivityBackup(int userId) { 14414 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14415 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 14416 } 14417 14418 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14419 try { 14420 final XmlSerializer serializer = new FastXmlSerializer(); 14421 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14422 serializer.startDocument(null, true); 14423 serializer.startTag(null, TAG_PREFERRED_BACKUP); 14424 14425 synchronized (mPackages) { 14426 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 14427 } 14428 14429 serializer.endTag(null, TAG_PREFERRED_BACKUP); 14430 serializer.endDocument(); 14431 serializer.flush(); 14432 } catch (Exception e) { 14433 if (DEBUG_BACKUP) { 14434 Slog.e(TAG, "Unable to write preferred activities for backup", e); 14435 } 14436 return null; 14437 } 14438 14439 return dataStream.toByteArray(); 14440 } 14441 14442 @Override restorePreferredActivities(byte[] backup, int userId)14443 public void restorePreferredActivities(byte[] backup, int userId) { 14444 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14445 throw new SecurityException("Only the system may call restorePreferredActivities()"); 14446 } 14447 14448 try { 14449 final XmlPullParser parser = Xml.newPullParser(); 14450 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14451 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 14452 new BlobXmlRestorer() { 14453 @Override 14454 public void apply(XmlPullParser parser, int userId) 14455 throws XmlPullParserException, IOException { 14456 synchronized (mPackages) { 14457 mSettings.readPreferredActivitiesLPw(parser, userId); 14458 } 14459 } 14460 } ); 14461 } catch (Exception e) { 14462 if (DEBUG_BACKUP) { 14463 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 14464 } 14465 } 14466 } 14467 14468 /** 14469 * Non-Binder method, support for the backup/restore mechanism: write the 14470 * default browser (etc) settings in its canonical XML format. Returns the default 14471 * browser XML representation as a byte array, or null if there is none. 14472 */ 14473 @Override getDefaultAppsBackup(int userId)14474 public byte[] getDefaultAppsBackup(int userId) { 14475 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14476 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 14477 } 14478 14479 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14480 try { 14481 final XmlSerializer serializer = new FastXmlSerializer(); 14482 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14483 serializer.startDocument(null, true); 14484 serializer.startTag(null, TAG_DEFAULT_APPS); 14485 14486 synchronized (mPackages) { 14487 mSettings.writeDefaultAppsLPr(serializer, userId); 14488 } 14489 14490 serializer.endTag(null, TAG_DEFAULT_APPS); 14491 serializer.endDocument(); 14492 serializer.flush(); 14493 } catch (Exception e) { 14494 if (DEBUG_BACKUP) { 14495 Slog.e(TAG, "Unable to write default apps for backup", e); 14496 } 14497 return null; 14498 } 14499 14500 return dataStream.toByteArray(); 14501 } 14502 14503 @Override restoreDefaultApps(byte[] backup, int userId)14504 public void restoreDefaultApps(byte[] backup, int userId) { 14505 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14506 throw new SecurityException("Only the system may call restoreDefaultApps()"); 14507 } 14508 14509 try { 14510 final XmlPullParser parser = Xml.newPullParser(); 14511 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14512 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 14513 new BlobXmlRestorer() { 14514 @Override 14515 public void apply(XmlPullParser parser, int userId) 14516 throws XmlPullParserException, IOException { 14517 synchronized (mPackages) { 14518 mSettings.readDefaultAppsLPw(parser, userId); 14519 } 14520 } 14521 } ); 14522 } catch (Exception e) { 14523 if (DEBUG_BACKUP) { 14524 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 14525 } 14526 } 14527 } 14528 14529 @Override getIntentFilterVerificationBackup(int userId)14530 public byte[] getIntentFilterVerificationBackup(int userId) { 14531 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14532 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 14533 } 14534 14535 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 14536 try { 14537 final XmlSerializer serializer = new FastXmlSerializer(); 14538 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 14539 serializer.startDocument(null, true); 14540 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 14541 14542 synchronized (mPackages) { 14543 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 14544 } 14545 14546 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 14547 serializer.endDocument(); 14548 serializer.flush(); 14549 } catch (Exception e) { 14550 if (DEBUG_BACKUP) { 14551 Slog.e(TAG, "Unable to write default apps for backup", e); 14552 } 14553 return null; 14554 } 14555 14556 return dataStream.toByteArray(); 14557 } 14558 14559 @Override restoreIntentFilterVerification(byte[] backup, int userId)14560 public void restoreIntentFilterVerification(byte[] backup, int userId) { 14561 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 14562 throw new SecurityException("Only the system may call restorePreferredActivities()"); 14563 } 14564 14565 try { 14566 final XmlPullParser parser = Xml.newPullParser(); 14567 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 14568 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 14569 new BlobXmlRestorer() { 14570 @Override 14571 public void apply(XmlPullParser parser, int userId) 14572 throws XmlPullParserException, IOException { 14573 synchronized (mPackages) { 14574 mSettings.readAllDomainVerificationsLPr(parser, userId); 14575 mSettings.writeLPr(); 14576 } 14577 } 14578 } ); 14579 } catch (Exception e) { 14580 if (DEBUG_BACKUP) { 14581 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 14582 } 14583 } 14584 } 14585 14586 @Override addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)14587 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 14588 int sourceUserId, int targetUserId, int flags) { 14589 mContext.enforceCallingOrSelfPermission( 14590 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 14591 int callingUid = Binder.getCallingUid(); 14592 enforceOwnerRights(ownerPackage, callingUid); 14593 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 14594 if (intentFilter.countActions() == 0) { 14595 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 14596 return; 14597 } 14598 synchronized (mPackages) { 14599 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 14600 ownerPackage, targetUserId, flags); 14601 CrossProfileIntentResolver resolver = 14602 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 14603 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 14604 // We have all those whose filter is equal. Now checking if the rest is equal as well. 14605 if (existing != null) { 14606 int size = existing.size(); 14607 for (int i = 0; i < size; i++) { 14608 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 14609 return; 14610 } 14611 } 14612 } 14613 resolver.addFilter(newFilter); 14614 scheduleWritePackageRestrictionsLocked(sourceUserId); 14615 } 14616 } 14617 14618 @Override clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage)14619 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 14620 mContext.enforceCallingOrSelfPermission( 14621 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 14622 int callingUid = Binder.getCallingUid(); 14623 enforceOwnerRights(ownerPackage, callingUid); 14624 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 14625 synchronized (mPackages) { 14626 CrossProfileIntentResolver resolver = 14627 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 14628 ArraySet<CrossProfileIntentFilter> set = 14629 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 14630 for (CrossProfileIntentFilter filter : set) { 14631 if (filter.getOwnerPackage().equals(ownerPackage)) { 14632 resolver.removeFilter(filter); 14633 } 14634 } 14635 scheduleWritePackageRestrictionsLocked(sourceUserId); 14636 } 14637 } 14638 14639 // Enforcing that callingUid is owning pkg on userId enforceOwnerRights(String pkg, int callingUid)14640 private void enforceOwnerRights(String pkg, int callingUid) { 14641 // The system owns everything. 14642 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 14643 return; 14644 } 14645 int callingUserId = UserHandle.getUserId(callingUid); 14646 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 14647 if (pi == null) { 14648 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 14649 + callingUserId); 14650 } 14651 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 14652 throw new SecurityException("Calling uid " + callingUid 14653 + " does not own package " + pkg); 14654 } 14655 } 14656 14657 @Override getHomeActivities(List<ResolveInfo> allHomeCandidates)14658 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 14659 Intent intent = new Intent(Intent.ACTION_MAIN); 14660 intent.addCategory(Intent.CATEGORY_HOME); 14661 14662 final int callingUserId = UserHandle.getCallingUserId(); 14663 List<ResolveInfo> list = queryIntentActivities(intent, null, 14664 PackageManager.GET_META_DATA, callingUserId); 14665 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 14666 true, false, false, callingUserId); 14667 14668 allHomeCandidates.clear(); 14669 if (list != null) { 14670 for (ResolveInfo ri : list) { 14671 allHomeCandidates.add(ri); 14672 } 14673 } 14674 return (preferred == null || preferred.activityInfo == null) 14675 ? null 14676 : new ComponentName(preferred.activityInfo.packageName, 14677 preferred.activityInfo.name); 14678 } 14679 14680 @Override setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)14681 public void setApplicationEnabledSetting(String appPackageName, 14682 int newState, int flags, int userId, String callingPackage) { 14683 if (!sUserManager.exists(userId)) return; 14684 if (callingPackage == null) { 14685 callingPackage = Integer.toString(Binder.getCallingUid()); 14686 } 14687 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 14688 } 14689 14690 @Override setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)14691 public void setComponentEnabledSetting(ComponentName componentName, 14692 int newState, int flags, int userId) { 14693 if (!sUserManager.exists(userId)) return; 14694 setEnabledSetting(componentName.getPackageName(), 14695 componentName.getClassName(), newState, flags, userId, null); 14696 } 14697 setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)14698 private void setEnabledSetting(final String packageName, String className, int newState, 14699 final int flags, int userId, String callingPackage) { 14700 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 14701 || newState == COMPONENT_ENABLED_STATE_ENABLED 14702 || newState == COMPONENT_ENABLED_STATE_DISABLED 14703 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 14704 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 14705 throw new IllegalArgumentException("Invalid new component state: " 14706 + newState); 14707 } 14708 PackageSetting pkgSetting; 14709 final int uid = Binder.getCallingUid(); 14710 final int permission = mContext.checkCallingOrSelfPermission( 14711 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 14712 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 14713 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 14714 boolean sendNow = false; 14715 boolean isApp = (className == null); 14716 String componentName = isApp ? packageName : className; 14717 int packageUid = -1; 14718 ArrayList<String> components; 14719 14720 // writer 14721 synchronized (mPackages) { 14722 pkgSetting = mSettings.mPackages.get(packageName); 14723 if (pkgSetting == null) { 14724 if (className == null) { 14725 throw new IllegalArgumentException( 14726 "Unknown package: " + packageName); 14727 } 14728 throw new IllegalArgumentException( 14729 "Unknown component: " + packageName 14730 + "/" + className); 14731 } 14732 // Allow root and verify that userId is not being specified by a different user 14733 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 14734 throw new SecurityException( 14735 "Permission Denial: attempt to change component state from pid=" 14736 + Binder.getCallingPid() 14737 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 14738 } 14739 if (className == null) { 14740 // We're dealing with an application/package level state change 14741 if (pkgSetting.getEnabled(userId) == newState) { 14742 // Nothing to do 14743 return; 14744 } 14745 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 14746 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 14747 // Don't care about who enables an app. 14748 callingPackage = null; 14749 } 14750 pkgSetting.setEnabled(newState, userId, callingPackage); 14751 // pkgSetting.pkg.mSetEnabled = newState; 14752 } else { 14753 // We're dealing with a component level state change 14754 // First, verify that this is a valid class name. 14755 PackageParser.Package pkg = pkgSetting.pkg; 14756 if (pkg == null || !pkg.hasComponentClassName(className)) { 14757 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 14758 throw new IllegalArgumentException("Component class " + className 14759 + " does not exist in " + packageName); 14760 } else { 14761 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 14762 + className + " does not exist in " + packageName); 14763 } 14764 } 14765 switch (newState) { 14766 case COMPONENT_ENABLED_STATE_ENABLED: 14767 if (!pkgSetting.enableComponentLPw(className, userId)) { 14768 return; 14769 } 14770 break; 14771 case COMPONENT_ENABLED_STATE_DISABLED: 14772 if (!pkgSetting.disableComponentLPw(className, userId)) { 14773 return; 14774 } 14775 break; 14776 case COMPONENT_ENABLED_STATE_DEFAULT: 14777 if (!pkgSetting.restoreComponentLPw(className, userId)) { 14778 return; 14779 } 14780 break; 14781 default: 14782 Slog.e(TAG, "Invalid new component state: " + newState); 14783 return; 14784 } 14785 } 14786 scheduleWritePackageRestrictionsLocked(userId); 14787 components = mPendingBroadcasts.get(userId, packageName); 14788 final boolean newPackage = components == null; 14789 if (newPackage) { 14790 components = new ArrayList<String>(); 14791 } 14792 if (!components.contains(componentName)) { 14793 components.add(componentName); 14794 } 14795 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 14796 sendNow = true; 14797 // Purge entry from pending broadcast list if another one exists already 14798 // since we are sending one right away. 14799 mPendingBroadcasts.remove(userId, packageName); 14800 } else { 14801 if (newPackage) { 14802 mPendingBroadcasts.put(userId, packageName, components); 14803 } 14804 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 14805 // Schedule a message 14806 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 14807 } 14808 } 14809 } 14810 14811 long callingId = Binder.clearCallingIdentity(); 14812 try { 14813 if (sendNow) { 14814 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 14815 sendPackageChangedBroadcast(packageName, 14816 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 14817 } 14818 } finally { 14819 Binder.restoreCallingIdentity(callingId); 14820 } 14821 } 14822 sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)14823 private void sendPackageChangedBroadcast(String packageName, 14824 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 14825 if (DEBUG_INSTALL) 14826 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 14827 + componentNames); 14828 Bundle extras = new Bundle(4); 14829 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 14830 String nameList[] = new String[componentNames.size()]; 14831 componentNames.toArray(nameList); 14832 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 14833 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 14834 extras.putInt(Intent.EXTRA_UID, packageUid); 14835 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 14836 new int[] {UserHandle.getUserId(packageUid)}); 14837 } 14838 14839 @Override setPackageStoppedState(String packageName, boolean stopped, int userId)14840 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 14841 if (!sUserManager.exists(userId)) return; 14842 final int uid = Binder.getCallingUid(); 14843 final int permission = mContext.checkCallingOrSelfPermission( 14844 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 14845 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 14846 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 14847 // writer 14848 synchronized (mPackages) { 14849 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 14850 allowedByPermission, uid, userId)) { 14851 scheduleWritePackageRestrictionsLocked(userId); 14852 } 14853 } 14854 } 14855 14856 @Override getInstallerPackageName(String packageName)14857 public String getInstallerPackageName(String packageName) { 14858 // reader 14859 synchronized (mPackages) { 14860 return mSettings.getInstallerPackageNameLPr(packageName); 14861 } 14862 } 14863 14864 @Override getApplicationEnabledSetting(String packageName, int userId)14865 public int getApplicationEnabledSetting(String packageName, int userId) { 14866 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 14867 int uid = Binder.getCallingUid(); 14868 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 14869 // reader 14870 synchronized (mPackages) { 14871 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 14872 } 14873 } 14874 14875 @Override getComponentEnabledSetting(ComponentName componentName, int userId)14876 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 14877 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 14878 int uid = Binder.getCallingUid(); 14879 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 14880 // reader 14881 synchronized (mPackages) { 14882 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 14883 } 14884 } 14885 14886 @Override enterSafeMode()14887 public void enterSafeMode() { 14888 enforceSystemOrRoot("Only the system can request entering safe mode"); 14889 14890 if (!mSystemReady) { 14891 mSafeMode = true; 14892 } 14893 } 14894 14895 @Override systemReady()14896 public void systemReady() { 14897 mSystemReady = true; 14898 14899 // Read the compatibilty setting when the system is ready. 14900 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 14901 mContext.getContentResolver(), 14902 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 14903 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 14904 if (DEBUG_SETTINGS) { 14905 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 14906 } 14907 14908 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 14909 14910 synchronized (mPackages) { 14911 // Verify that all of the preferred activity components actually 14912 // exist. It is possible for applications to be updated and at 14913 // that point remove a previously declared activity component that 14914 // had been set as a preferred activity. We try to clean this up 14915 // the next time we encounter that preferred activity, but it is 14916 // possible for the user flow to never be able to return to that 14917 // situation so here we do a sanity check to make sure we haven't 14918 // left any junk around. 14919 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 14920 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 14921 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 14922 removed.clear(); 14923 for (PreferredActivity pa : pir.filterSet()) { 14924 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 14925 removed.add(pa); 14926 } 14927 } 14928 if (removed.size() > 0) { 14929 for (int r=0; r<removed.size(); r++) { 14930 PreferredActivity pa = removed.get(r); 14931 Slog.w(TAG, "Removing dangling preferred activity: " 14932 + pa.mPref.mComponent); 14933 pir.removeFilter(pa); 14934 } 14935 mSettings.writePackageRestrictionsLPr( 14936 mSettings.mPreferredActivities.keyAt(i)); 14937 } 14938 } 14939 14940 for (int userId : UserManagerService.getInstance().getUserIds()) { 14941 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 14942 grantPermissionsUserIds = ArrayUtils.appendInt( 14943 grantPermissionsUserIds, userId); 14944 } 14945 } 14946 } 14947 sUserManager.systemReady(); 14948 14949 // If we upgraded grant all default permissions before kicking off. 14950 for (int userId : grantPermissionsUserIds) { 14951 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 14952 } 14953 14954 // Kick off any messages waiting for system ready 14955 if (mPostSystemReadyMessages != null) { 14956 for (Message msg : mPostSystemReadyMessages) { 14957 msg.sendToTarget(); 14958 } 14959 mPostSystemReadyMessages = null; 14960 } 14961 14962 // Watch for external volumes that come and go over time 14963 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14964 storage.registerListener(mStorageListener); 14965 14966 mInstallerService.systemReady(); 14967 mPackageDexOptimizer.systemReady(); 14968 14969 MountServiceInternal mountServiceInternal = LocalServices.getService( 14970 MountServiceInternal.class); 14971 mountServiceInternal.addExternalStoragePolicy( 14972 new MountServiceInternal.ExternalStorageMountPolicy() { 14973 @Override 14974 public int getMountMode(int uid, String packageName) { 14975 if (Process.isIsolated(uid)) { 14976 return Zygote.MOUNT_EXTERNAL_NONE; 14977 } 14978 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 14979 return Zygote.MOUNT_EXTERNAL_DEFAULT; 14980 } 14981 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 14982 return Zygote.MOUNT_EXTERNAL_DEFAULT; 14983 } 14984 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 14985 return Zygote.MOUNT_EXTERNAL_READ; 14986 } 14987 return Zygote.MOUNT_EXTERNAL_WRITE; 14988 } 14989 14990 @Override 14991 public boolean hasExternalStorage(int uid, String packageName) { 14992 return true; 14993 } 14994 }); 14995 } 14996 14997 @Override isSafeMode()14998 public boolean isSafeMode() { 14999 return mSafeMode; 15000 } 15001 15002 @Override hasSystemUidErrors()15003 public boolean hasSystemUidErrors() { 15004 return mHasSystemUidErrors; 15005 } 15006 arrayToString(int[] array)15007 static String arrayToString(int[] array) { 15008 StringBuffer buf = new StringBuffer(128); 15009 buf.append('['); 15010 if (array != null) { 15011 for (int i=0; i<array.length; i++) { 15012 if (i > 0) buf.append(", "); 15013 buf.append(array[i]); 15014 } 15015 } 15016 buf.append(']'); 15017 return buf.toString(); 15018 } 15019 15020 static class DumpState { 15021 public static final int DUMP_LIBS = 1 << 0; 15022 public static final int DUMP_FEATURES = 1 << 1; 15023 public static final int DUMP_RESOLVERS = 1 << 2; 15024 public static final int DUMP_PERMISSIONS = 1 << 3; 15025 public static final int DUMP_PACKAGES = 1 << 4; 15026 public static final int DUMP_SHARED_USERS = 1 << 5; 15027 public static final int DUMP_MESSAGES = 1 << 6; 15028 public static final int DUMP_PROVIDERS = 1 << 7; 15029 public static final int DUMP_VERIFIERS = 1 << 8; 15030 public static final int DUMP_PREFERRED = 1 << 9; 15031 public static final int DUMP_PREFERRED_XML = 1 << 10; 15032 public static final int DUMP_KEYSETS = 1 << 11; 15033 public static final int DUMP_VERSION = 1 << 12; 15034 public static final int DUMP_INSTALLS = 1 << 13; 15035 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14; 15036 public static final int DUMP_DOMAIN_PREFERRED = 1 << 15; 15037 15038 public static final int OPTION_SHOW_FILTERS = 1 << 0; 15039 15040 private int mTypes; 15041 15042 private int mOptions; 15043 15044 private boolean mTitlePrinted; 15045 15046 private SharedUserSetting mSharedUser; 15047 isDumping(int type)15048 public boolean isDumping(int type) { 15049 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 15050 return true; 15051 } 15052 15053 return (mTypes & type) != 0; 15054 } 15055 setDump(int type)15056 public void setDump(int type) { 15057 mTypes |= type; 15058 } 15059 isOptionEnabled(int option)15060 public boolean isOptionEnabled(int option) { 15061 return (mOptions & option) != 0; 15062 } 15063 setOptionEnabled(int option)15064 public void setOptionEnabled(int option) { 15065 mOptions |= option; 15066 } 15067 onTitlePrinted()15068 public boolean onTitlePrinted() { 15069 final boolean printed = mTitlePrinted; 15070 mTitlePrinted = true; 15071 return printed; 15072 } 15073 getTitlePrinted()15074 public boolean getTitlePrinted() { 15075 return mTitlePrinted; 15076 } 15077 setTitlePrinted(boolean enabled)15078 public void setTitlePrinted(boolean enabled) { 15079 mTitlePrinted = enabled; 15080 } 15081 getSharedUser()15082 public SharedUserSetting getSharedUser() { 15083 return mSharedUser; 15084 } 15085 setSharedUser(SharedUserSetting user)15086 public void setSharedUser(SharedUserSetting user) { 15087 mSharedUser = user; 15088 } 15089 } 15090 15091 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)15092 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 15093 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 15094 != PackageManager.PERMISSION_GRANTED) { 15095 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 15096 + Binder.getCallingPid() 15097 + ", uid=" + Binder.getCallingUid() 15098 + " without permission " 15099 + android.Manifest.permission.DUMP); 15100 return; 15101 } 15102 15103 DumpState dumpState = new DumpState(); 15104 boolean fullPreferred = false; 15105 boolean checkin = false; 15106 15107 String packageName = null; 15108 ArraySet<String> permissionNames = null; 15109 15110 int opti = 0; 15111 while (opti < args.length) { 15112 String opt = args[opti]; 15113 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 15114 break; 15115 } 15116 opti++; 15117 15118 if ("-a".equals(opt)) { 15119 // Right now we only know how to print all. 15120 } else if ("-h".equals(opt)) { 15121 pw.println("Package manager dump options:"); 15122 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 15123 pw.println(" --checkin: dump for a checkin"); 15124 pw.println(" -f: print details of intent filters"); 15125 pw.println(" -h: print this help"); 15126 pw.println(" cmd may be one of:"); 15127 pw.println(" l[ibraries]: list known shared libraries"); 15128 pw.println(" f[ibraries]: list device features"); 15129 pw.println(" k[eysets]: print known keysets"); 15130 pw.println(" r[esolvers]: dump intent resolvers"); 15131 pw.println(" perm[issions]: dump permissions"); 15132 pw.println(" permission [name ...]: dump declaration and use of given permission"); 15133 pw.println(" pref[erred]: print preferred package settings"); 15134 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 15135 pw.println(" prov[iders]: dump content providers"); 15136 pw.println(" p[ackages]: dump installed packages"); 15137 pw.println(" s[hared-users]: dump shared user IDs"); 15138 pw.println(" m[essages]: print collected runtime messages"); 15139 pw.println(" v[erifiers]: print package verifier info"); 15140 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 15141 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 15142 pw.println(" version: print database version info"); 15143 pw.println(" write: write current settings now"); 15144 pw.println(" installs: details about install sessions"); 15145 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 15146 pw.println(" <package.name>: info about given package"); 15147 return; 15148 } else if ("--checkin".equals(opt)) { 15149 checkin = true; 15150 } else if ("-f".equals(opt)) { 15151 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 15152 } else { 15153 pw.println("Unknown argument: " + opt + "; use -h for help"); 15154 } 15155 } 15156 15157 // Is the caller requesting to dump a particular piece of data? 15158 if (opti < args.length) { 15159 String cmd = args[opti]; 15160 opti++; 15161 // Is this a package name? 15162 if ("android".equals(cmd) || cmd.contains(".")) { 15163 packageName = cmd; 15164 // When dumping a single package, we always dump all of its 15165 // filter information since the amount of data will be reasonable. 15166 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 15167 } else if ("check-permission".equals(cmd)) { 15168 if (opti >= args.length) { 15169 pw.println("Error: check-permission missing permission argument"); 15170 return; 15171 } 15172 String perm = args[opti]; 15173 opti++; 15174 if (opti >= args.length) { 15175 pw.println("Error: check-permission missing package argument"); 15176 return; 15177 } 15178 String pkg = args[opti]; 15179 opti++; 15180 int user = UserHandle.getUserId(Binder.getCallingUid()); 15181 if (opti < args.length) { 15182 try { 15183 user = Integer.parseInt(args[opti]); 15184 } catch (NumberFormatException e) { 15185 pw.println("Error: check-permission user argument is not a number: " 15186 + args[opti]); 15187 return; 15188 } 15189 } 15190 pw.println(checkPermission(perm, pkg, user)); 15191 return; 15192 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 15193 dumpState.setDump(DumpState.DUMP_LIBS); 15194 } else if ("f".equals(cmd) || "features".equals(cmd)) { 15195 dumpState.setDump(DumpState.DUMP_FEATURES); 15196 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 15197 dumpState.setDump(DumpState.DUMP_RESOLVERS); 15198 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 15199 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 15200 } else if ("permission".equals(cmd)) { 15201 if (opti >= args.length) { 15202 pw.println("Error: permission requires permission name"); 15203 return; 15204 } 15205 permissionNames = new ArraySet<>(); 15206 while (opti < args.length) { 15207 permissionNames.add(args[opti]); 15208 opti++; 15209 } 15210 dumpState.setDump(DumpState.DUMP_PERMISSIONS 15211 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 15212 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 15213 dumpState.setDump(DumpState.DUMP_PREFERRED); 15214 } else if ("preferred-xml".equals(cmd)) { 15215 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 15216 if (opti < args.length && "--full".equals(args[opti])) { 15217 fullPreferred = true; 15218 opti++; 15219 } 15220 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 15221 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 15222 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 15223 dumpState.setDump(DumpState.DUMP_PACKAGES); 15224 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 15225 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 15226 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 15227 dumpState.setDump(DumpState.DUMP_PROVIDERS); 15228 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 15229 dumpState.setDump(DumpState.DUMP_MESSAGES); 15230 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 15231 dumpState.setDump(DumpState.DUMP_VERIFIERS); 15232 } else if ("i".equals(cmd) || "ifv".equals(cmd) 15233 || "intent-filter-verifiers".equals(cmd)) { 15234 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 15235 } else if ("version".equals(cmd)) { 15236 dumpState.setDump(DumpState.DUMP_VERSION); 15237 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 15238 dumpState.setDump(DumpState.DUMP_KEYSETS); 15239 } else if ("installs".equals(cmd)) { 15240 dumpState.setDump(DumpState.DUMP_INSTALLS); 15241 } else if ("write".equals(cmd)) { 15242 synchronized (mPackages) { 15243 mSettings.writeLPr(); 15244 pw.println("Settings written."); 15245 return; 15246 } 15247 } 15248 } 15249 15250 if (checkin) { 15251 pw.println("vers,1"); 15252 } 15253 15254 // reader 15255 synchronized (mPackages) { 15256 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 15257 if (!checkin) { 15258 if (dumpState.onTitlePrinted()) 15259 pw.println(); 15260 pw.println("Database versions:"); 15261 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 15262 } 15263 } 15264 15265 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 15266 if (!checkin) { 15267 if (dumpState.onTitlePrinted()) 15268 pw.println(); 15269 pw.println("Verifiers:"); 15270 pw.print(" Required: "); 15271 pw.print(mRequiredVerifierPackage); 15272 pw.print(" (uid="); 15273 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 15274 pw.println(")"); 15275 } else if (mRequiredVerifierPackage != null) { 15276 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 15277 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 15278 } 15279 } 15280 15281 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 15282 packageName == null) { 15283 if (mIntentFilterVerifierComponent != null) { 15284 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 15285 if (!checkin) { 15286 if (dumpState.onTitlePrinted()) 15287 pw.println(); 15288 pw.println("Intent Filter Verifier:"); 15289 pw.print(" Using: "); 15290 pw.print(verifierPackageName); 15291 pw.print(" (uid="); 15292 pw.print(getPackageUid(verifierPackageName, 0)); 15293 pw.println(")"); 15294 } else if (verifierPackageName != null) { 15295 pw.print("ifv,"); pw.print(verifierPackageName); 15296 pw.print(","); pw.println(getPackageUid(verifierPackageName, 0)); 15297 } 15298 } else { 15299 pw.println(); 15300 pw.println("No Intent Filter Verifier available!"); 15301 } 15302 } 15303 15304 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 15305 boolean printedHeader = false; 15306 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 15307 while (it.hasNext()) { 15308 String name = it.next(); 15309 SharedLibraryEntry ent = mSharedLibraries.get(name); 15310 if (!checkin) { 15311 if (!printedHeader) { 15312 if (dumpState.onTitlePrinted()) 15313 pw.println(); 15314 pw.println("Libraries:"); 15315 printedHeader = true; 15316 } 15317 pw.print(" "); 15318 } else { 15319 pw.print("lib,"); 15320 } 15321 pw.print(name); 15322 if (!checkin) { 15323 pw.print(" -> "); 15324 } 15325 if (ent.path != null) { 15326 if (!checkin) { 15327 pw.print("(jar) "); 15328 pw.print(ent.path); 15329 } else { 15330 pw.print(",jar,"); 15331 pw.print(ent.path); 15332 } 15333 } else { 15334 if (!checkin) { 15335 pw.print("(apk) "); 15336 pw.print(ent.apk); 15337 } else { 15338 pw.print(",apk,"); 15339 pw.print(ent.apk); 15340 } 15341 } 15342 pw.println(); 15343 } 15344 } 15345 15346 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 15347 if (dumpState.onTitlePrinted()) 15348 pw.println(); 15349 if (!checkin) { 15350 pw.println("Features:"); 15351 } 15352 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 15353 while (it.hasNext()) { 15354 String name = it.next(); 15355 if (!checkin) { 15356 pw.print(" "); 15357 } else { 15358 pw.print("feat,"); 15359 } 15360 pw.println(name); 15361 } 15362 } 15363 15364 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 15365 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 15366 : "Activity Resolver Table:", " ", packageName, 15367 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15368 dumpState.setTitlePrinted(true); 15369 } 15370 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 15371 : "Receiver Resolver Table:", " ", packageName, 15372 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15373 dumpState.setTitlePrinted(true); 15374 } 15375 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 15376 : "Service Resolver Table:", " ", packageName, 15377 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15378 dumpState.setTitlePrinted(true); 15379 } 15380 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 15381 : "Provider Resolver Table:", " ", packageName, 15382 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 15383 dumpState.setTitlePrinted(true); 15384 } 15385 } 15386 15387 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 15388 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15389 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15390 int user = mSettings.mPreferredActivities.keyAt(i); 15391 if (pir.dump(pw, 15392 dumpState.getTitlePrinted() 15393 ? "\nPreferred Activities User " + user + ":" 15394 : "Preferred Activities User " + user + ":", " ", 15395 packageName, true, false)) { 15396 dumpState.setTitlePrinted(true); 15397 } 15398 } 15399 } 15400 15401 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 15402 pw.flush(); 15403 FileOutputStream fout = new FileOutputStream(fd); 15404 BufferedOutputStream str = new BufferedOutputStream(fout); 15405 XmlSerializer serializer = new FastXmlSerializer(); 15406 try { 15407 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 15408 serializer.startDocument(null, true); 15409 serializer.setFeature( 15410 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 15411 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 15412 serializer.endDocument(); 15413 serializer.flush(); 15414 } catch (IllegalArgumentException e) { 15415 pw.println("Failed writing: " + e); 15416 } catch (IllegalStateException e) { 15417 pw.println("Failed writing: " + e); 15418 } catch (IOException e) { 15419 pw.println("Failed writing: " + e); 15420 } 15421 } 15422 15423 if (!checkin 15424 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 15425 && packageName == null) { 15426 pw.println(); 15427 int count = mSettings.mPackages.size(); 15428 if (count == 0) { 15429 pw.println("No applications!"); 15430 pw.println(); 15431 } else { 15432 final String prefix = " "; 15433 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 15434 if (allPackageSettings.size() == 0) { 15435 pw.println("No domain preferred apps!"); 15436 pw.println(); 15437 } else { 15438 pw.println("App verification status:"); 15439 pw.println(); 15440 count = 0; 15441 for (PackageSetting ps : allPackageSettings) { 15442 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 15443 if (ivi == null || ivi.getPackageName() == null) continue; 15444 pw.println(prefix + "Package: " + ivi.getPackageName()); 15445 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 15446 pw.println(prefix + "Status: " + ivi.getStatusString()); 15447 pw.println(); 15448 count++; 15449 } 15450 if (count == 0) { 15451 pw.println(prefix + "No app verification established."); 15452 pw.println(); 15453 } 15454 for (int userId : sUserManager.getUserIds()) { 15455 pw.println("App linkages for user " + userId + ":"); 15456 pw.println(); 15457 count = 0; 15458 for (PackageSetting ps : allPackageSettings) { 15459 final long status = ps.getDomainVerificationStatusForUser(userId); 15460 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 15461 continue; 15462 } 15463 pw.println(prefix + "Package: " + ps.name); 15464 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 15465 String statusStr = IntentFilterVerificationInfo. 15466 getStatusStringFromValue(status); 15467 pw.println(prefix + "Status: " + statusStr); 15468 pw.println(); 15469 count++; 15470 } 15471 if (count == 0) { 15472 pw.println(prefix + "No configured app linkages."); 15473 pw.println(); 15474 } 15475 } 15476 } 15477 } 15478 } 15479 15480 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 15481 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 15482 if (packageName == null && permissionNames == null) { 15483 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 15484 if (iperm == 0) { 15485 if (dumpState.onTitlePrinted()) 15486 pw.println(); 15487 pw.println("AppOp Permissions:"); 15488 } 15489 pw.print(" AppOp Permission "); 15490 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 15491 pw.println(":"); 15492 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 15493 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 15494 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 15495 } 15496 } 15497 } 15498 } 15499 15500 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 15501 boolean printedSomething = false; 15502 for (PackageParser.Provider p : mProviders.mProviders.values()) { 15503 if (packageName != null && !packageName.equals(p.info.packageName)) { 15504 continue; 15505 } 15506 if (!printedSomething) { 15507 if (dumpState.onTitlePrinted()) 15508 pw.println(); 15509 pw.println("Registered ContentProviders:"); 15510 printedSomething = true; 15511 } 15512 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 15513 pw.print(" "); pw.println(p.toString()); 15514 } 15515 printedSomething = false; 15516 for (Map.Entry<String, PackageParser.Provider> entry : 15517 mProvidersByAuthority.entrySet()) { 15518 PackageParser.Provider p = entry.getValue(); 15519 if (packageName != null && !packageName.equals(p.info.packageName)) { 15520 continue; 15521 } 15522 if (!printedSomething) { 15523 if (dumpState.onTitlePrinted()) 15524 pw.println(); 15525 pw.println("ContentProvider Authorities:"); 15526 printedSomething = true; 15527 } 15528 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 15529 pw.print(" "); pw.println(p.toString()); 15530 if (p.info != null && p.info.applicationInfo != null) { 15531 final String appInfo = p.info.applicationInfo.toString(); 15532 pw.print(" applicationInfo="); pw.println(appInfo); 15533 } 15534 } 15535 } 15536 15537 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 15538 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 15539 } 15540 15541 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 15542 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 15543 } 15544 15545 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 15546 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 15547 } 15548 15549 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 15550 // XXX should handle packageName != null by dumping only install data that 15551 // the given package is involved with. 15552 if (dumpState.onTitlePrinted()) pw.println(); 15553 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 15554 } 15555 15556 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 15557 if (dumpState.onTitlePrinted()) pw.println(); 15558 mSettings.dumpReadMessagesLPr(pw, dumpState); 15559 15560 pw.println(); 15561 pw.println("Package warning messages:"); 15562 BufferedReader in = null; 15563 String line = null; 15564 try { 15565 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 15566 while ((line = in.readLine()) != null) { 15567 if (line.contains("ignored: updated version")) continue; 15568 pw.println(line); 15569 } 15570 } catch (IOException ignored) { 15571 } finally { 15572 IoUtils.closeQuietly(in); 15573 } 15574 } 15575 15576 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 15577 BufferedReader in = null; 15578 String line = null; 15579 try { 15580 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 15581 while ((line = in.readLine()) != null) { 15582 if (line.contains("ignored: updated version")) continue; 15583 pw.print("msg,"); 15584 pw.println(line); 15585 } 15586 } catch (IOException ignored) { 15587 } finally { 15588 IoUtils.closeQuietly(in); 15589 } 15590 } 15591 } 15592 } 15593 dumpDomainString(String packageName)15594 private String dumpDomainString(String packageName) { 15595 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName); 15596 List<IntentFilter> filters = getAllIntentFilters(packageName); 15597 15598 ArraySet<String> result = new ArraySet<>(); 15599 if (iviList.size() > 0) { 15600 for (IntentFilterVerificationInfo ivi : iviList) { 15601 for (String host : ivi.getDomains()) { 15602 result.add(host); 15603 } 15604 } 15605 } 15606 if (filters != null && filters.size() > 0) { 15607 for (IntentFilter filter : filters) { 15608 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 15609 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 15610 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 15611 result.addAll(filter.getHostsList()); 15612 } 15613 } 15614 } 15615 15616 StringBuilder sb = new StringBuilder(result.size() * 16); 15617 for (String domain : result) { 15618 if (sb.length() > 0) sb.append(" "); 15619 sb.append(domain); 15620 } 15621 return sb.toString(); 15622 } 15623 15624 // ------- apps on sdcard specific code ------- 15625 static final boolean DEBUG_SD_INSTALL = false; 15626 15627 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 15628 15629 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 15630 15631 private boolean mMediaMounted = false; 15632 getEncryptKey()15633 static String getEncryptKey() { 15634 try { 15635 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 15636 SD_ENCRYPTION_KEYSTORE_NAME); 15637 if (sdEncKey == null) { 15638 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 15639 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 15640 if (sdEncKey == null) { 15641 Slog.e(TAG, "Failed to create encryption keys"); 15642 return null; 15643 } 15644 } 15645 return sdEncKey; 15646 } catch (NoSuchAlgorithmException nsae) { 15647 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 15648 return null; 15649 } catch (IOException ioe) { 15650 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 15651 return null; 15652 } 15653 } 15654 15655 /* 15656 * Update media status on PackageManager. 15657 */ 15658 @Override updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)15659 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 15660 int callingUid = Binder.getCallingUid(); 15661 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15662 throw new SecurityException("Media status can only be updated by the system"); 15663 } 15664 // reader; this apparently protects mMediaMounted, but should probably 15665 // be a different lock in that case. 15666 synchronized (mPackages) { 15667 Log.i(TAG, "Updating external media status from " 15668 + (mMediaMounted ? "mounted" : "unmounted") + " to " 15669 + (mediaStatus ? "mounted" : "unmounted")); 15670 if (DEBUG_SD_INSTALL) 15671 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 15672 + ", mMediaMounted=" + mMediaMounted); 15673 if (mediaStatus == mMediaMounted) { 15674 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 15675 : 0, -1); 15676 mHandler.sendMessage(msg); 15677 return; 15678 } 15679 mMediaMounted = mediaStatus; 15680 } 15681 // Queue up an async operation since the package installation may take a 15682 // little while. 15683 mHandler.post(new Runnable() { 15684 public void run() { 15685 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 15686 } 15687 }); 15688 } 15689 15690 /** 15691 * Called by MountService when the initial ASECs to scan are available. 15692 * Should block until all the ASEC containers are finished being scanned. 15693 */ scanAvailableAsecs()15694 public void scanAvailableAsecs() { 15695 updateExternalMediaStatusInner(true, false, false); 15696 if (mShouldRestoreconData) { 15697 SELinuxMMAC.setRestoreconDone(); 15698 mShouldRestoreconData = false; 15699 } 15700 } 15701 15702 /* 15703 * Collect information of applications on external media, map them against 15704 * existing containers and update information based on current mount status. 15705 * Please note that we always have to report status if reportStatus has been 15706 * set to true especially when unloading packages. 15707 */ updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)15708 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 15709 boolean externalStorage) { 15710 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 15711 int[] uidArr = EmptyArray.INT; 15712 15713 final String[] list = PackageHelper.getSecureContainerList(); 15714 if (ArrayUtils.isEmpty(list)) { 15715 Log.i(TAG, "No secure containers found"); 15716 } else { 15717 // Process list of secure containers and categorize them 15718 // as active or stale based on their package internal state. 15719 15720 // reader 15721 synchronized (mPackages) { 15722 for (String cid : list) { 15723 // Leave stages untouched for now; installer service owns them 15724 if (PackageInstallerService.isStageName(cid)) continue; 15725 15726 if (DEBUG_SD_INSTALL) 15727 Log.i(TAG, "Processing container " + cid); 15728 String pkgName = getAsecPackageName(cid); 15729 if (pkgName == null) { 15730 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 15731 continue; 15732 } 15733 if (DEBUG_SD_INSTALL) 15734 Log.i(TAG, "Looking for pkg : " + pkgName); 15735 15736 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15737 if (ps == null) { 15738 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 15739 continue; 15740 } 15741 15742 /* 15743 * Skip packages that are not external if we're unmounting 15744 * external storage. 15745 */ 15746 if (externalStorage && !isMounted && !isExternal(ps)) { 15747 continue; 15748 } 15749 15750 final AsecInstallArgs args = new AsecInstallArgs(cid, 15751 getAppDexInstructionSets(ps), ps.isForwardLocked()); 15752 // The package status is changed only if the code path 15753 // matches between settings and the container id. 15754 if (ps.codePathString != null 15755 && ps.codePathString.startsWith(args.getCodePath())) { 15756 if (DEBUG_SD_INSTALL) { 15757 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 15758 + " at code path: " + ps.codePathString); 15759 } 15760 15761 // We do have a valid package installed on sdcard 15762 processCids.put(args, ps.codePathString); 15763 final int uid = ps.appId; 15764 if (uid != -1) { 15765 uidArr = ArrayUtils.appendInt(uidArr, uid); 15766 } 15767 } else { 15768 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 15769 + ps.codePathString); 15770 } 15771 } 15772 } 15773 15774 Arrays.sort(uidArr); 15775 } 15776 15777 // Process packages with valid entries. 15778 if (isMounted) { 15779 if (DEBUG_SD_INSTALL) 15780 Log.i(TAG, "Loading packages"); 15781 loadMediaPackages(processCids, uidArr, externalStorage); 15782 startCleaningPackages(); 15783 mInstallerService.onSecureContainersAvailable(); 15784 } else { 15785 if (DEBUG_SD_INSTALL) 15786 Log.i(TAG, "Unloading packages"); 15787 unloadMediaPackages(processCids, uidArr, reportStatus); 15788 } 15789 } 15790 sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver)15791 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15792 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 15793 final int size = infos.size(); 15794 final String[] packageNames = new String[size]; 15795 final int[] packageUids = new int[size]; 15796 for (int i = 0; i < size; i++) { 15797 final ApplicationInfo info = infos.get(i); 15798 packageNames[i] = info.packageName; 15799 packageUids[i] = info.uid; 15800 } 15801 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 15802 finishedReceiver); 15803 } 15804 sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)15805 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15806 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 15807 sendResourcesChangedBroadcast(mediaStatus, replacing, 15808 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 15809 } 15810 sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver)15811 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 15812 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 15813 int size = pkgList.length; 15814 if (size > 0) { 15815 // Send broadcasts here 15816 Bundle extras = new Bundle(); 15817 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 15818 if (uidArr != null) { 15819 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 15820 } 15821 if (replacing) { 15822 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 15823 } 15824 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 15825 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 15826 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 15827 } 15828 } 15829 15830 /* 15831 * Look at potentially valid container ids from processCids If package 15832 * information doesn't match the one on record or package scanning fails, 15833 * the cid is added to list of removeCids. We currently don't delete stale 15834 * containers. 15835 */ loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, boolean externalStorage)15836 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 15837 boolean externalStorage) { 15838 ArrayList<String> pkgList = new ArrayList<String>(); 15839 Set<AsecInstallArgs> keys = processCids.keySet(); 15840 15841 for (AsecInstallArgs args : keys) { 15842 String codePath = processCids.get(args); 15843 if (DEBUG_SD_INSTALL) 15844 Log.i(TAG, "Loading container : " + args.cid); 15845 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15846 try { 15847 // Make sure there are no container errors first. 15848 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 15849 Slog.e(TAG, "Failed to mount cid : " + args.cid 15850 + " when installing from sdcard"); 15851 continue; 15852 } 15853 // Check code path here. 15854 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 15855 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 15856 + " does not match one in settings " + codePath); 15857 continue; 15858 } 15859 // Parse package 15860 int parseFlags = mDefParseFlags; 15861 if (args.isExternalAsec()) { 15862 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 15863 } 15864 if (args.isFwdLocked()) { 15865 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 15866 } 15867 15868 synchronized (mInstallLock) { 15869 PackageParser.Package pkg = null; 15870 try { 15871 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null); 15872 } catch (PackageManagerException e) { 15873 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 15874 } 15875 // Scan the package 15876 if (pkg != null) { 15877 /* 15878 * TODO why is the lock being held? doPostInstall is 15879 * called in other places without the lock. This needs 15880 * to be straightened out. 15881 */ 15882 // writer 15883 synchronized (mPackages) { 15884 retCode = PackageManager.INSTALL_SUCCEEDED; 15885 pkgList.add(pkg.packageName); 15886 // Post process args 15887 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 15888 pkg.applicationInfo.uid); 15889 } 15890 } else { 15891 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 15892 } 15893 } 15894 15895 } finally { 15896 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 15897 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 15898 } 15899 } 15900 } 15901 // writer 15902 synchronized (mPackages) { 15903 // If the platform SDK has changed since the last time we booted, 15904 // we need to re-grant app permission to catch any new ones that 15905 // appear. This is really a hack, and means that apps can in some 15906 // cases get permissions that the user didn't initially explicitly 15907 // allow... it would be nice to have some better way to handle 15908 // this situation. 15909 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 15910 : mSettings.getInternalVersion(); 15911 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 15912 : StorageManager.UUID_PRIVATE_INTERNAL; 15913 15914 int updateFlags = UPDATE_PERMISSIONS_ALL; 15915 if (ver.sdkVersion != mSdkVersion) { 15916 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 15917 + mSdkVersion + "; regranting permissions for external"); 15918 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 15919 } 15920 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 15921 15922 // Yay, everything is now upgraded 15923 ver.forceCurrent(); 15924 15925 // can downgrade to reader 15926 // Persist settings 15927 mSettings.writeLPr(); 15928 } 15929 // Send a broadcast to let everyone know we are done processing 15930 if (pkgList.size() > 0) { 15931 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 15932 } 15933 } 15934 15935 /* 15936 * Utility method to unload a list of specified containers 15937 */ unloadAllContainers(Set<AsecInstallArgs> cidArgs)15938 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 15939 // Just unmount all valid containers. 15940 for (AsecInstallArgs arg : cidArgs) { 15941 synchronized (mInstallLock) { 15942 arg.doPostDeleteLI(false); 15943 } 15944 } 15945 } 15946 15947 /* 15948 * Unload packages mounted on external media. This involves deleting package 15949 * data from internal structures, sending broadcasts about diabled packages, 15950 * gc'ing to free up references, unmounting all secure containers 15951 * corresponding to packages on external media, and posting a 15952 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 15953 * that we always have to post this message if status has been requested no 15954 * matter what. 15955 */ unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)15956 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 15957 final boolean reportStatus) { 15958 if (DEBUG_SD_INSTALL) 15959 Log.i(TAG, "unloading media packages"); 15960 ArrayList<String> pkgList = new ArrayList<String>(); 15961 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 15962 final Set<AsecInstallArgs> keys = processCids.keySet(); 15963 for (AsecInstallArgs args : keys) { 15964 String pkgName = args.getPackageName(); 15965 if (DEBUG_SD_INSTALL) 15966 Log.i(TAG, "Trying to unload pkg : " + pkgName); 15967 // Delete package internally 15968 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 15969 synchronized (mInstallLock) { 15970 boolean res = deletePackageLI(pkgName, null, false, null, null, 15971 PackageManager.DELETE_KEEP_DATA, outInfo, false); 15972 if (res) { 15973 pkgList.add(pkgName); 15974 } else { 15975 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 15976 failedList.add(args); 15977 } 15978 } 15979 } 15980 15981 // reader 15982 synchronized (mPackages) { 15983 // We didn't update the settings after removing each package; 15984 // write them now for all packages. 15985 mSettings.writeLPr(); 15986 } 15987 15988 // We have to absolutely send UPDATED_MEDIA_STATUS only 15989 // after confirming that all the receivers processed the ordered 15990 // broadcast when packages get disabled, force a gc to clean things up. 15991 // and unload all the containers. 15992 if (pkgList.size() > 0) { 15993 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 15994 new IIntentReceiver.Stub() { 15995 public void performReceive(Intent intent, int resultCode, String data, 15996 Bundle extras, boolean ordered, boolean sticky, 15997 int sendingUser) throws RemoteException { 15998 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 15999 reportStatus ? 1 : 0, 1, keys); 16000 mHandler.sendMessage(msg); 16001 } 16002 }); 16003 } else { 16004 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 16005 keys); 16006 mHandler.sendMessage(msg); 16007 } 16008 } 16009 loadPrivatePackages(final VolumeInfo vol)16010 private void loadPrivatePackages(final VolumeInfo vol) { 16011 mHandler.post(new Runnable() { 16012 @Override 16013 public void run() { 16014 loadPrivatePackagesInner(vol); 16015 } 16016 }); 16017 } 16018 loadPrivatePackagesInner(VolumeInfo vol)16019 private void loadPrivatePackagesInner(VolumeInfo vol) { 16020 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 16021 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 16022 16023 final VersionInfo ver; 16024 final List<PackageSetting> packages; 16025 synchronized (mPackages) { 16026 ver = mSettings.findOrCreateVersion(vol.fsUuid); 16027 packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 16028 } 16029 16030 for (PackageSetting ps : packages) { 16031 synchronized (mInstallLock) { 16032 final PackageParser.Package pkg; 16033 try { 16034 pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null); 16035 loaded.add(pkg.applicationInfo); 16036 } catch (PackageManagerException e) { 16037 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 16038 } 16039 16040 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 16041 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 16042 } 16043 } 16044 } 16045 16046 synchronized (mPackages) { 16047 int updateFlags = UPDATE_PERMISSIONS_ALL; 16048 if (ver.sdkVersion != mSdkVersion) { 16049 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 16050 + mSdkVersion + "; regranting permissions for " + vol.fsUuid); 16051 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 16052 } 16053 updatePermissionsLPw(null, null, vol.fsUuid, updateFlags); 16054 16055 // Yay, everything is now upgraded 16056 ver.forceCurrent(); 16057 16058 mSettings.writeLPr(); 16059 } 16060 16061 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 16062 sendResourcesChangedBroadcast(true, false, loaded, null); 16063 } 16064 unloadPrivatePackages(final VolumeInfo vol)16065 private void unloadPrivatePackages(final VolumeInfo vol) { 16066 mHandler.post(new Runnable() { 16067 @Override 16068 public void run() { 16069 unloadPrivatePackagesInner(vol); 16070 } 16071 }); 16072 } 16073 unloadPrivatePackagesInner(VolumeInfo vol)16074 private void unloadPrivatePackagesInner(VolumeInfo vol) { 16075 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 16076 synchronized (mInstallLock) { 16077 synchronized (mPackages) { 16078 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 16079 for (PackageSetting ps : packages) { 16080 if (ps.pkg == null) continue; 16081 16082 final ApplicationInfo info = ps.pkg.applicationInfo; 16083 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 16084 if (deletePackageLI(ps.name, null, false, null, null, 16085 PackageManager.DELETE_KEEP_DATA, outInfo, false)) { 16086 unloaded.add(info); 16087 } else { 16088 Slog.w(TAG, "Failed to unload " + ps.codePath); 16089 } 16090 } 16091 16092 mSettings.writeLPr(); 16093 } 16094 } 16095 16096 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 16097 sendResourcesChangedBroadcast(false, false, unloaded, null); 16098 } 16099 16100 /** 16101 * Examine all users present on given mounted volume, and destroy data 16102 * belonging to users that are no longer valid, or whose user ID has been 16103 * recycled. 16104 */ reconcileUsers(String volumeUuid)16105 private void reconcileUsers(String volumeUuid) { 16106 final File[] files = FileUtils 16107 .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid)); 16108 for (File file : files) { 16109 if (!file.isDirectory()) continue; 16110 16111 final int userId; 16112 final UserInfo info; 16113 try { 16114 userId = Integer.parseInt(file.getName()); 16115 info = sUserManager.getUserInfo(userId); 16116 } catch (NumberFormatException e) { 16117 Slog.w(TAG, "Invalid user directory " + file); 16118 continue; 16119 } 16120 16121 boolean destroyUser = false; 16122 if (info == null) { 16123 logCriticalInfo(Log.WARN, "Destroying user directory " + file 16124 + " because no matching user was found"); 16125 destroyUser = true; 16126 } else { 16127 try { 16128 UserManagerService.enforceSerialNumber(file, info.serialNumber); 16129 } catch (IOException e) { 16130 logCriticalInfo(Log.WARN, "Destroying user directory " + file 16131 + " because we failed to enforce serial number: " + e); 16132 destroyUser = true; 16133 } 16134 } 16135 16136 if (destroyUser) { 16137 synchronized (mInstallLock) { 16138 mInstaller.removeUserDataDirs(volumeUuid, userId); 16139 } 16140 } 16141 } 16142 16143 final UserManager um = mContext.getSystemService(UserManager.class); 16144 for (UserInfo user : um.getUsers()) { 16145 final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id); 16146 if (userDir.exists()) continue; 16147 16148 try { 16149 UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id); 16150 UserManagerService.enforceSerialNumber(userDir, user.serialNumber); 16151 } catch (IOException e) { 16152 Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e); 16153 } 16154 } 16155 } 16156 16157 /** 16158 * Examine all apps present on given mounted volume, and destroy apps that 16159 * aren't expected, either due to uninstallation or reinstallation on 16160 * another volume. 16161 */ reconcileApps(String volumeUuid)16162 private void reconcileApps(String volumeUuid) { 16163 final File[] files = FileUtils 16164 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 16165 for (File file : files) { 16166 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 16167 && !PackageInstallerService.isStageName(file.getName()); 16168 if (!isPackage) { 16169 // Ignore entries which are not packages 16170 continue; 16171 } 16172 16173 boolean destroyApp = false; 16174 String packageName = null; 16175 try { 16176 final PackageLite pkg = PackageParser.parsePackageLite(file, 16177 PackageParser.PARSE_MUST_BE_APK); 16178 packageName = pkg.packageName; 16179 16180 synchronized (mPackages) { 16181 final PackageSetting ps = mSettings.mPackages.get(packageName); 16182 if (ps == null) { 16183 logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + " 16184 + volumeUuid + " because we found no install record"); 16185 destroyApp = true; 16186 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 16187 logCriticalInfo(Log.WARN, "Destroying " + packageName + " on " 16188 + volumeUuid + " because we expected it on " + ps.volumeUuid); 16189 destroyApp = true; 16190 } 16191 } 16192 16193 } catch (PackageParserException e) { 16194 logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e); 16195 destroyApp = true; 16196 } 16197 16198 if (destroyApp) { 16199 synchronized (mInstallLock) { 16200 if (packageName != null) { 16201 removeDataDirsLI(volumeUuid, packageName); 16202 } 16203 if (file.isDirectory()) { 16204 mInstaller.rmPackageDir(file.getAbsolutePath()); 16205 } else { 16206 file.delete(); 16207 } 16208 } 16209 } 16210 } 16211 } 16212 unfreezePackage(String packageName)16213 private void unfreezePackage(String packageName) { 16214 synchronized (mPackages) { 16215 final PackageSetting ps = mSettings.mPackages.get(packageName); 16216 if (ps != null) { 16217 ps.frozen = false; 16218 } 16219 } 16220 } 16221 16222 @Override movePackage(final String packageName, final String volumeUuid)16223 public int movePackage(final String packageName, final String volumeUuid) { 16224 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 16225 16226 final int moveId = mNextMoveId.getAndIncrement(); 16227 mHandler.post(new Runnable() { 16228 @Override 16229 public void run() { 16230 try { 16231 movePackageInternal(packageName, volumeUuid, moveId); 16232 } catch (PackageManagerException e) { 16233 Slog.w(TAG, "Failed to move " + packageName, e); 16234 mMoveCallbacks.notifyStatusChanged(moveId, 16235 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 16236 } 16237 } 16238 }); 16239 return moveId; 16240 } 16241 movePackageInternal(final String packageName, final String volumeUuid, final int moveId)16242 private void movePackageInternal(final String packageName, final String volumeUuid, 16243 final int moveId) throws PackageManagerException { 16244 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 16245 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16246 final PackageManager pm = mContext.getPackageManager(); 16247 16248 final boolean currentAsec; 16249 final String currentVolumeUuid; 16250 final File codeFile; 16251 final String installerPackageName; 16252 final String packageAbiOverride; 16253 final int appId; 16254 final String seinfo; 16255 final String label; 16256 16257 // reader 16258 synchronized (mPackages) { 16259 final PackageParser.Package pkg = mPackages.get(packageName); 16260 final PackageSetting ps = mSettings.mPackages.get(packageName); 16261 if (pkg == null || ps == null) { 16262 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 16263 } 16264 16265 if (pkg.applicationInfo.isSystemApp()) { 16266 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 16267 "Cannot move system application"); 16268 } 16269 16270 if (pkg.applicationInfo.isExternalAsec()) { 16271 currentAsec = true; 16272 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 16273 } else if (pkg.applicationInfo.isForwardLocked()) { 16274 currentAsec = true; 16275 currentVolumeUuid = "forward_locked"; 16276 } else { 16277 currentAsec = false; 16278 currentVolumeUuid = ps.volumeUuid; 16279 16280 final File probe = new File(pkg.codePath); 16281 final File probeOat = new File(probe, "oat"); 16282 if (!probe.isDirectory() || !probeOat.isDirectory()) { 16283 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16284 "Move only supported for modern cluster style installs"); 16285 } 16286 } 16287 16288 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 16289 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16290 "Package already moved to " + volumeUuid); 16291 } 16292 16293 if (ps.frozen) { 16294 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 16295 "Failed to move already frozen package"); 16296 } 16297 ps.frozen = true; 16298 16299 codeFile = new File(pkg.codePath); 16300 installerPackageName = ps.installerPackageName; 16301 packageAbiOverride = ps.cpuAbiOverrideString; 16302 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 16303 seinfo = pkg.applicationInfo.seinfo; 16304 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 16305 } 16306 16307 // Now that we're guarded by frozen state, kill app during move 16308 final long token = Binder.clearCallingIdentity(); 16309 try { 16310 killApplication(packageName, appId, "move pkg"); 16311 } finally { 16312 Binder.restoreCallingIdentity(token); 16313 } 16314 16315 final Bundle extras = new Bundle(); 16316 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 16317 extras.putString(Intent.EXTRA_TITLE, label); 16318 mMoveCallbacks.notifyCreated(moveId, extras); 16319 16320 int installFlags; 16321 final boolean moveCompleteApp; 16322 final File measurePath; 16323 16324 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 16325 installFlags = INSTALL_INTERNAL; 16326 moveCompleteApp = !currentAsec; 16327 measurePath = Environment.getDataAppDirectory(volumeUuid); 16328 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 16329 installFlags = INSTALL_EXTERNAL; 16330 moveCompleteApp = false; 16331 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 16332 } else { 16333 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 16334 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 16335 || !volume.isMountedWritable()) { 16336 unfreezePackage(packageName); 16337 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16338 "Move location not mounted private volume"); 16339 } 16340 16341 Preconditions.checkState(!currentAsec); 16342 16343 installFlags = INSTALL_INTERNAL; 16344 moveCompleteApp = true; 16345 measurePath = Environment.getDataAppDirectory(volumeUuid); 16346 } 16347 16348 final PackageStats stats = new PackageStats(null, -1); 16349 synchronized (mInstaller) { 16350 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 16351 unfreezePackage(packageName); 16352 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16353 "Failed to measure package size"); 16354 } 16355 } 16356 16357 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 16358 + stats.dataSize); 16359 16360 final long startFreeBytes = measurePath.getFreeSpace(); 16361 final long sizeBytes; 16362 if (moveCompleteApp) { 16363 sizeBytes = stats.codeSize + stats.dataSize; 16364 } else { 16365 sizeBytes = stats.codeSize; 16366 } 16367 16368 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 16369 unfreezePackage(packageName); 16370 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 16371 "Not enough free space to move"); 16372 } 16373 16374 mMoveCallbacks.notifyStatusChanged(moveId, 10); 16375 16376 final CountDownLatch installedLatch = new CountDownLatch(1); 16377 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 16378 @Override 16379 public void onUserActionRequired(Intent intent) throws RemoteException { 16380 throw new IllegalStateException(); 16381 } 16382 16383 @Override 16384 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 16385 Bundle extras) throws RemoteException { 16386 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 16387 + PackageManager.installStatusToString(returnCode, msg)); 16388 16389 installedLatch.countDown(); 16390 16391 // Regardless of success or failure of the move operation, 16392 // always unfreeze the package 16393 unfreezePackage(packageName); 16394 16395 final int status = PackageManager.installStatusToPublicStatus(returnCode); 16396 switch (status) { 16397 case PackageInstaller.STATUS_SUCCESS: 16398 mMoveCallbacks.notifyStatusChanged(moveId, 16399 PackageManager.MOVE_SUCCEEDED); 16400 break; 16401 case PackageInstaller.STATUS_FAILURE_STORAGE: 16402 mMoveCallbacks.notifyStatusChanged(moveId, 16403 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 16404 break; 16405 default: 16406 mMoveCallbacks.notifyStatusChanged(moveId, 16407 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 16408 break; 16409 } 16410 } 16411 }; 16412 16413 final MoveInfo move; 16414 if (moveCompleteApp) { 16415 // Kick off a thread to report progress estimates 16416 new Thread() { 16417 @Override 16418 public void run() { 16419 while (true) { 16420 try { 16421 if (installedLatch.await(1, TimeUnit.SECONDS)) { 16422 break; 16423 } 16424 } catch (InterruptedException ignored) { 16425 } 16426 16427 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 16428 final int progress = 10 + (int) MathUtils.constrain( 16429 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 16430 mMoveCallbacks.notifyStatusChanged(moveId, progress); 16431 } 16432 } 16433 }.start(); 16434 16435 final String dataAppName = codeFile.getName(); 16436 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 16437 dataAppName, appId, seinfo); 16438 } else { 16439 move = null; 16440 } 16441 16442 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 16443 16444 final Message msg = mHandler.obtainMessage(INIT_COPY); 16445 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 16446 msg.obj = new InstallParams(origin, move, installObserver, installFlags, 16447 installerPackageName, volumeUuid, null, user, packageAbiOverride, null); 16448 mHandler.sendMessage(msg); 16449 } 16450 16451 @Override movePrimaryStorage(String volumeUuid)16452 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 16453 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 16454 16455 final int realMoveId = mNextMoveId.getAndIncrement(); 16456 final Bundle extras = new Bundle(); 16457 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 16458 mMoveCallbacks.notifyCreated(realMoveId, extras); 16459 16460 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 16461 @Override 16462 public void onCreated(int moveId, Bundle extras) { 16463 // Ignored 16464 } 16465 16466 @Override 16467 public void onStatusChanged(int moveId, int status, long estMillis) { 16468 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 16469 } 16470 }; 16471 16472 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16473 storage.setPrimaryStorageUuid(volumeUuid, callback); 16474 return realMoveId; 16475 } 16476 16477 @Override getMoveStatus(int moveId)16478 public int getMoveStatus(int moveId) { 16479 mContext.enforceCallingOrSelfPermission( 16480 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16481 return mMoveCallbacks.mLastStatus.get(moveId); 16482 } 16483 16484 @Override registerMoveCallback(IPackageMoveObserver callback)16485 public void registerMoveCallback(IPackageMoveObserver callback) { 16486 mContext.enforceCallingOrSelfPermission( 16487 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16488 mMoveCallbacks.register(callback); 16489 } 16490 16491 @Override unregisterMoveCallback(IPackageMoveObserver callback)16492 public void unregisterMoveCallback(IPackageMoveObserver callback) { 16493 mContext.enforceCallingOrSelfPermission( 16494 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 16495 mMoveCallbacks.unregister(callback); 16496 } 16497 16498 @Override setInstallLocation(int loc)16499 public boolean setInstallLocation(int loc) { 16500 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 16501 null); 16502 if (getInstallLocation() == loc) { 16503 return true; 16504 } 16505 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 16506 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 16507 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 16508 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 16509 return true; 16510 } 16511 return false; 16512 } 16513 16514 @Override getInstallLocation()16515 public int getInstallLocation() { 16516 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 16517 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 16518 PackageHelper.APP_INSTALL_AUTO); 16519 } 16520 16521 /** Called by UserManagerService */ cleanUpUserLILPw(UserManagerService userManager, int userHandle)16522 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 16523 mDirtyUsers.remove(userHandle); 16524 mSettings.removeUserLPw(userHandle); 16525 mPendingBroadcasts.remove(userHandle); 16526 if (mInstaller != null) { 16527 // Technically, we shouldn't be doing this with the package lock 16528 // held. However, this is very rare, and there is already so much 16529 // other disk I/O going on, that we'll let it slide for now. 16530 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16531 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 16532 final String volumeUuid = vol.getFsUuid(); 16533 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 16534 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 16535 } 16536 } 16537 mUserNeedsBadging.delete(userHandle); 16538 removeUnusedPackagesLILPw(userManager, userHandle); 16539 } 16540 16541 /** 16542 * We're removing userHandle and would like to remove any downloaded packages 16543 * that are no longer in use by any other user. 16544 * @param userHandle the user being removed 16545 */ removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle)16546 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 16547 final boolean DEBUG_CLEAN_APKS = false; 16548 int [] users = userManager.getUserIdsLPr(); 16549 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 16550 while (psit.hasNext()) { 16551 PackageSetting ps = psit.next(); 16552 if (ps.pkg == null) { 16553 continue; 16554 } 16555 final String packageName = ps.pkg.packageName; 16556 // Skip over if system app 16557 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 16558 continue; 16559 } 16560 if (DEBUG_CLEAN_APKS) { 16561 Slog.i(TAG, "Checking package " + packageName); 16562 } 16563 boolean keep = false; 16564 for (int i = 0; i < users.length; i++) { 16565 if (users[i] != userHandle && ps.getInstalled(users[i])) { 16566 keep = true; 16567 if (DEBUG_CLEAN_APKS) { 16568 Slog.i(TAG, " Keeping package " + packageName + " for user " 16569 + users[i]); 16570 } 16571 break; 16572 } 16573 } 16574 if (!keep) { 16575 if (DEBUG_CLEAN_APKS) { 16576 Slog.i(TAG, " Removing package " + packageName); 16577 } 16578 mHandler.post(new Runnable() { 16579 public void run() { 16580 deletePackageX(packageName, userHandle, 0); 16581 } //end run 16582 }); 16583 } 16584 } 16585 } 16586 16587 /** Called by UserManagerService */ createNewUserLILPw(int userHandle)16588 void createNewUserLILPw(int userHandle) { 16589 if (mInstaller != null) { 16590 mInstaller.createUserConfig(userHandle); 16591 mSettings.createNewUserLILPw(this, mInstaller, userHandle); 16592 applyFactoryDefaultBrowserLPw(userHandle); 16593 primeDomainVerificationsLPw(userHandle); 16594 } 16595 } 16596 newUserCreated(final int userHandle)16597 void newUserCreated(final int userHandle) { 16598 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 16599 } 16600 16601 @Override getVerifierDeviceIdentity()16602 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 16603 mContext.enforceCallingOrSelfPermission( 16604 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 16605 "Only package verification agents can read the verifier device identity"); 16606 16607 synchronized (mPackages) { 16608 return mSettings.getVerifierDeviceIdentityLPw(); 16609 } 16610 } 16611 16612 @Override setPermissionEnforced(String permission, boolean enforced)16613 public void setPermissionEnforced(String permission, boolean enforced) { 16614 // TODO: Now that we no longer change GID for storage, this should to away. 16615 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 16616 "setPermissionEnforced"); 16617 if (READ_EXTERNAL_STORAGE.equals(permission)) { 16618 synchronized (mPackages) { 16619 if (mSettings.mReadExternalStorageEnforced == null 16620 || mSettings.mReadExternalStorageEnforced != enforced) { 16621 mSettings.mReadExternalStorageEnforced = enforced; 16622 mSettings.writeLPr(); 16623 } 16624 } 16625 // kill any non-foreground processes so we restart them and 16626 // grant/revoke the GID. 16627 final IActivityManager am = ActivityManagerNative.getDefault(); 16628 if (am != null) { 16629 final long token = Binder.clearCallingIdentity(); 16630 try { 16631 am.killProcessesBelowForeground("setPermissionEnforcement"); 16632 } catch (RemoteException e) { 16633 } finally { 16634 Binder.restoreCallingIdentity(token); 16635 } 16636 } 16637 } else { 16638 throw new IllegalArgumentException("No selective enforcement for " + permission); 16639 } 16640 } 16641 16642 @Override 16643 @Deprecated isPermissionEnforced(String permission)16644 public boolean isPermissionEnforced(String permission) { 16645 return true; 16646 } 16647 16648 @Override isStorageLow()16649 public boolean isStorageLow() { 16650 final long token = Binder.clearCallingIdentity(); 16651 try { 16652 final DeviceStorageMonitorInternal 16653 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 16654 if (dsm != null) { 16655 return dsm.isMemoryLow(); 16656 } else { 16657 return false; 16658 } 16659 } finally { 16660 Binder.restoreCallingIdentity(token); 16661 } 16662 } 16663 16664 @Override getPackageInstaller()16665 public IPackageInstaller getPackageInstaller() { 16666 return mInstallerService; 16667 } 16668 userNeedsBadging(int userId)16669 private boolean userNeedsBadging(int userId) { 16670 int index = mUserNeedsBadging.indexOfKey(userId); 16671 if (index < 0) { 16672 final UserInfo userInfo; 16673 final long token = Binder.clearCallingIdentity(); 16674 try { 16675 userInfo = sUserManager.getUserInfo(userId); 16676 } finally { 16677 Binder.restoreCallingIdentity(token); 16678 } 16679 final boolean b; 16680 if (userInfo != null && userInfo.isManagedProfile()) { 16681 b = true; 16682 } else { 16683 b = false; 16684 } 16685 mUserNeedsBadging.put(userId, b); 16686 return b; 16687 } 16688 return mUserNeedsBadging.valueAt(index); 16689 } 16690 16691 @Override getKeySetByAlias(String packageName, String alias)16692 public KeySet getKeySetByAlias(String packageName, String alias) { 16693 if (packageName == null || alias == null) { 16694 return null; 16695 } 16696 synchronized(mPackages) { 16697 final PackageParser.Package pkg = mPackages.get(packageName); 16698 if (pkg == null) { 16699 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16700 throw new IllegalArgumentException("Unknown package: " + packageName); 16701 } 16702 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16703 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 16704 } 16705 } 16706 16707 @Override getSigningKeySet(String packageName)16708 public KeySet getSigningKeySet(String packageName) { 16709 if (packageName == null) { 16710 return null; 16711 } 16712 synchronized(mPackages) { 16713 final PackageParser.Package pkg = mPackages.get(packageName); 16714 if (pkg == null) { 16715 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16716 throw new IllegalArgumentException("Unknown package: " + packageName); 16717 } 16718 if (pkg.applicationInfo.uid != Binder.getCallingUid() 16719 && Process.SYSTEM_UID != Binder.getCallingUid()) { 16720 throw new SecurityException("May not access signing KeySet of other apps."); 16721 } 16722 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16723 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 16724 } 16725 } 16726 16727 @Override isPackageSignedByKeySet(String packageName, KeySet ks)16728 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 16729 if (packageName == null || ks == null) { 16730 return false; 16731 } 16732 synchronized(mPackages) { 16733 final PackageParser.Package pkg = mPackages.get(packageName); 16734 if (pkg == null) { 16735 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16736 throw new IllegalArgumentException("Unknown package: " + packageName); 16737 } 16738 IBinder ksh = ks.getToken(); 16739 if (ksh instanceof KeySetHandle) { 16740 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16741 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 16742 } 16743 return false; 16744 } 16745 } 16746 16747 @Override isPackageSignedByKeySetExactly(String packageName, KeySet ks)16748 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 16749 if (packageName == null || ks == null) { 16750 return false; 16751 } 16752 synchronized(mPackages) { 16753 final PackageParser.Package pkg = mPackages.get(packageName); 16754 if (pkg == null) { 16755 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 16756 throw new IllegalArgumentException("Unknown package: " + packageName); 16757 } 16758 IBinder ksh = ks.getToken(); 16759 if (ksh instanceof KeySetHandle) { 16760 KeySetManagerService ksms = mSettings.mKeySetManagerService; 16761 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 16762 } 16763 return false; 16764 } 16765 } 16766 getUsageStatsIfNoPackageUsageInfo()16767 public void getUsageStatsIfNoPackageUsageInfo() { 16768 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 16769 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 16770 if (usm == null) { 16771 throw new IllegalStateException("UsageStatsManager must be initialized"); 16772 } 16773 long now = System.currentTimeMillis(); 16774 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 16775 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 16776 String packageName = entry.getKey(); 16777 PackageParser.Package pkg = mPackages.get(packageName); 16778 if (pkg == null) { 16779 continue; 16780 } 16781 UsageStats usage = entry.getValue(); 16782 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 16783 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 16784 } 16785 } 16786 } 16787 16788 /** 16789 * Check and throw if the given before/after packages would be considered a 16790 * downgrade. 16791 */ checkDowngrade(PackageParser.Package before, PackageInfoLite after)16792 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 16793 throws PackageManagerException { 16794 if (after.versionCode < before.mVersionCode) { 16795 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16796 "Update version code " + after.versionCode + " is older than current " 16797 + before.mVersionCode); 16798 } else if (after.versionCode == before.mVersionCode) { 16799 if (after.baseRevisionCode < before.baseRevisionCode) { 16800 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16801 "Update base revision code " + after.baseRevisionCode 16802 + " is older than current " + before.baseRevisionCode); 16803 } 16804 16805 if (!ArrayUtils.isEmpty(after.splitNames)) { 16806 for (int i = 0; i < after.splitNames.length; i++) { 16807 final String splitName = after.splitNames[i]; 16808 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 16809 if (j != -1) { 16810 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 16811 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 16812 "Update split " + splitName + " revision code " 16813 + after.splitRevisionCodes[i] + " is older than current " 16814 + before.splitRevisionCodes[j]); 16815 } 16816 } 16817 } 16818 } 16819 } 16820 } 16821 16822 private static class MoveCallbacks extends Handler { 16823 private static final int MSG_CREATED = 1; 16824 private static final int MSG_STATUS_CHANGED = 2; 16825 16826 private final RemoteCallbackList<IPackageMoveObserver> 16827 mCallbacks = new RemoteCallbackList<>(); 16828 16829 private final SparseIntArray mLastStatus = new SparseIntArray(); 16830 MoveCallbacks(Looper looper)16831 public MoveCallbacks(Looper looper) { 16832 super(looper); 16833 } 16834 register(IPackageMoveObserver callback)16835 public void register(IPackageMoveObserver callback) { 16836 mCallbacks.register(callback); 16837 } 16838 unregister(IPackageMoveObserver callback)16839 public void unregister(IPackageMoveObserver callback) { 16840 mCallbacks.unregister(callback); 16841 } 16842 16843 @Override handleMessage(Message msg)16844 public void handleMessage(Message msg) { 16845 final SomeArgs args = (SomeArgs) msg.obj; 16846 final int n = mCallbacks.beginBroadcast(); 16847 for (int i = 0; i < n; i++) { 16848 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 16849 try { 16850 invokeCallback(callback, msg.what, args); 16851 } catch (RemoteException ignored) { 16852 } 16853 } 16854 mCallbacks.finishBroadcast(); 16855 args.recycle(); 16856 } 16857 invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)16858 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 16859 throws RemoteException { 16860 switch (what) { 16861 case MSG_CREATED: { 16862 callback.onCreated(args.argi1, (Bundle) args.arg2); 16863 break; 16864 } 16865 case MSG_STATUS_CHANGED: { 16866 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 16867 break; 16868 } 16869 } 16870 } 16871 notifyCreated(int moveId, Bundle extras)16872 private void notifyCreated(int moveId, Bundle extras) { 16873 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 16874 16875 final SomeArgs args = SomeArgs.obtain(); 16876 args.argi1 = moveId; 16877 args.arg2 = extras; 16878 obtainMessage(MSG_CREATED, args).sendToTarget(); 16879 } 16880 notifyStatusChanged(int moveId, int status)16881 private void notifyStatusChanged(int moveId, int status) { 16882 notifyStatusChanged(moveId, status, -1); 16883 } 16884 notifyStatusChanged(int moveId, int status, long estMillis)16885 private void notifyStatusChanged(int moveId, int status, long estMillis) { 16886 Slog.v(TAG, "Move " + moveId + " status " + status); 16887 16888 final SomeArgs args = SomeArgs.obtain(); 16889 args.argi1 = moveId; 16890 args.argi2 = status; 16891 args.arg3 = estMillis; 16892 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 16893 16894 synchronized (mLastStatus) { 16895 mLastStatus.put(moveId, status); 16896 } 16897 } 16898 } 16899 16900 private final class OnPermissionChangeListeners extends Handler { 16901 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 16902 16903 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 16904 new RemoteCallbackList<>(); 16905 OnPermissionChangeListeners(Looper looper)16906 public OnPermissionChangeListeners(Looper looper) { 16907 super(looper); 16908 } 16909 16910 @Override handleMessage(Message msg)16911 public void handleMessage(Message msg) { 16912 switch (msg.what) { 16913 case MSG_ON_PERMISSIONS_CHANGED: { 16914 final int uid = msg.arg1; 16915 handleOnPermissionsChanged(uid); 16916 } break; 16917 } 16918 } 16919 addListenerLocked(IOnPermissionsChangeListener listener)16920 public void addListenerLocked(IOnPermissionsChangeListener listener) { 16921 mPermissionListeners.register(listener); 16922 16923 } 16924 removeListenerLocked(IOnPermissionsChangeListener listener)16925 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 16926 mPermissionListeners.unregister(listener); 16927 } 16928 onPermissionsChanged(int uid)16929 public void onPermissionsChanged(int uid) { 16930 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 16931 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 16932 } 16933 } 16934 handleOnPermissionsChanged(int uid)16935 private void handleOnPermissionsChanged(int uid) { 16936 final int count = mPermissionListeners.beginBroadcast(); 16937 try { 16938 for (int i = 0; i < count; i++) { 16939 IOnPermissionsChangeListener callback = mPermissionListeners 16940 .getBroadcastItem(i); 16941 try { 16942 callback.onPermissionsChanged(uid); 16943 } catch (RemoteException e) { 16944 Log.e(TAG, "Permission listener is dead", e); 16945 } 16946 } 16947 } finally { 16948 mPermissionListeners.finishBroadcast(); 16949 } 16950 } 16951 } 16952 16953 private class PackageManagerInternalImpl extends PackageManagerInternal { 16954 @Override setLocationPackagesProvider(PackagesProvider provider)16955 public void setLocationPackagesProvider(PackagesProvider provider) { 16956 synchronized (mPackages) { 16957 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 16958 } 16959 } 16960 16961 @Override setImePackagesProvider(PackagesProvider provider)16962 public void setImePackagesProvider(PackagesProvider provider) { 16963 synchronized (mPackages) { 16964 mDefaultPermissionPolicy.setImePackagesProviderLPr(provider); 16965 } 16966 } 16967 16968 @Override setVoiceInteractionPackagesProvider(PackagesProvider provider)16969 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 16970 synchronized (mPackages) { 16971 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 16972 } 16973 } 16974 16975 @Override setSmsAppPackagesProvider(PackagesProvider provider)16976 public void setSmsAppPackagesProvider(PackagesProvider provider) { 16977 synchronized (mPackages) { 16978 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 16979 } 16980 } 16981 16982 @Override setDialerAppPackagesProvider(PackagesProvider provider)16983 public void setDialerAppPackagesProvider(PackagesProvider provider) { 16984 synchronized (mPackages) { 16985 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 16986 } 16987 } 16988 16989 @Override setSimCallManagerPackagesProvider(PackagesProvider provider)16990 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 16991 synchronized (mPackages) { 16992 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 16993 } 16994 } 16995 16996 @Override setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider)16997 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 16998 synchronized (mPackages) { 16999 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 17000 } 17001 } 17002 17003 @Override grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId)17004 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 17005 synchronized (mPackages) { 17006 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 17007 packageName, userId); 17008 } 17009 } 17010 17011 @Override grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId)17012 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 17013 synchronized (mPackages) { 17014 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 17015 packageName, userId); 17016 } 17017 } 17018 @Override grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId)17019 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 17020 synchronized (mPackages) { 17021 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 17022 packageName, userId); 17023 } 17024 } 17025 } 17026 17027 @Override grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId)17028 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 17029 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 17030 synchronized (mPackages) { 17031 final long identity = Binder.clearCallingIdentity(); 17032 try { 17033 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 17034 packageNames, userId); 17035 } finally { 17036 Binder.restoreCallingIdentity(identity); 17037 } 17038 } 17039 } 17040 enforceSystemOrPhoneCaller(String tag)17041 private static void enforceSystemOrPhoneCaller(String tag) { 17042 int callingUid = Binder.getCallingUid(); 17043 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 17044 throw new SecurityException( 17045 "Cannot call " + tag + " from UID " + callingUid); 17046 } 17047 } 17048 } 17049