Settings.java revision 30a23a5a7bcc1264ceaad93303176f1faff2f8c4
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.pm; 18 19import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 20import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 22import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 23import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 24import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 25import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 26import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 27import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 28import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 29import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; 30import static android.os.Process.PACKAGE_INFO_GID; 31import static android.os.Process.SYSTEM_UID; 32 33import static com.android.server.pm.PackageManagerService.DEBUG_DOMAIN_VERIFICATION; 34 35import android.annotation.NonNull; 36import android.annotation.Nullable; 37import android.content.ComponentName; 38import android.content.Intent; 39import android.content.IntentFilter; 40import android.content.pm.ActivityInfo; 41import android.content.pm.ApplicationInfo; 42import android.content.pm.ComponentInfo; 43import android.content.pm.IntentFilterVerificationInfo; 44import android.content.pm.PackageCleanItem; 45import android.content.pm.PackageManager; 46import android.content.pm.PackageParser; 47import android.content.pm.PackageUserState; 48import android.content.pm.PermissionInfo; 49import android.content.pm.ResolveInfo; 50import android.content.pm.Signature; 51import android.content.pm.UserInfo; 52import android.content.pm.VerifierDeviceIdentity; 53import android.net.Uri; 54import android.os.Binder; 55import android.os.Build; 56import android.os.Environment; 57import android.os.FileUtils; 58import android.os.Handler; 59import android.os.Message; 60import android.os.PatternMatcher; 61import android.os.Process; 62import android.os.SystemClock; 63import android.os.UserHandle; 64import android.os.UserManager; 65import android.os.storage.StorageManager; 66import android.service.pm.PackageServiceDumpProto; 67import android.text.TextUtils; 68import android.util.ArrayMap; 69import android.util.ArraySet; 70import android.util.AtomicFile; 71import android.util.Log; 72import android.util.LogPrinter; 73import android.util.Slog; 74import android.util.SparseArray; 75import android.util.SparseBooleanArray; 76import android.util.SparseIntArray; 77import android.util.SparseLongArray; 78import android.util.Xml; 79import android.util.proto.ProtoOutputStream; 80 81import com.android.internal.annotations.GuardedBy; 82import com.android.internal.os.BackgroundThread; 83import com.android.internal.util.ArrayUtils; 84import com.android.internal.util.FastXmlSerializer; 85import com.android.internal.util.IndentingPrintWriter; 86import com.android.internal.util.JournaledFile; 87import com.android.internal.util.XmlUtils; 88import com.android.server.pm.Installer.InstallerException; 89import com.android.server.pm.permission.BasePermission; 90import com.android.server.pm.permission.PermissionSettings; 91import com.android.server.pm.permission.PermissionsState; 92import com.android.server.pm.permission.PermissionsState.PermissionState; 93 94import libcore.io.IoUtils; 95 96import org.xmlpull.v1.XmlPullParser; 97import org.xmlpull.v1.XmlPullParserException; 98import org.xmlpull.v1.XmlSerializer; 99 100import java.io.BufferedInputStream; 101import java.io.BufferedOutputStream; 102import java.io.BufferedWriter; 103import java.io.File; 104import java.io.FileInputStream; 105import java.io.FileNotFoundException; 106import java.io.FileOutputStream; 107import java.io.IOException; 108import java.io.InputStream; 109import java.io.OutputStreamWriter; 110import java.io.PrintWriter; 111import java.nio.charset.Charset; 112import java.nio.charset.StandardCharsets; 113import java.text.SimpleDateFormat; 114import java.util.ArrayList; 115import java.util.Arrays; 116import java.util.Collection; 117import java.util.Collections; 118import java.util.Date; 119import java.util.Iterator; 120import java.util.List; 121import java.util.Map; 122import java.util.Map.Entry; 123import java.util.Objects; 124import java.util.Set; 125 126/** 127 * Holds information about dynamic settings. 128 */ 129public final class Settings { 130 private static final String TAG = "PackageSettings"; 131 132 /** 133 * Current version of the package database. Set it to the latest version in 134 * the {@link DatabaseVersion} class below to ensure the database upgrade 135 * doesn't happen repeatedly. 136 * <p> 137 * Note that care should be taken to make sure all database upgrades are 138 * idempotent. 139 */ 140 public static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 141 142 /** 143 * This class contains constants that can be referred to from upgrade code. 144 * Insert constant values here that describe the upgrade reason. The version 145 * code must be monotonically increasing. 146 */ 147 public static class DatabaseVersion { 148 /** 149 * The initial version of the database. 150 */ 151 public static final int FIRST_VERSION = 1; 152 153 /** 154 * Migrating the Signature array from the entire certificate chain to 155 * just the signing certificate. 156 */ 157 public static final int SIGNATURE_END_ENTITY = 2; 158 159 /** 160 * There was a window of time in 161 * {@link android.os.Build.VERSION_CODES#LOLLIPOP} where we persisted 162 * certificates after potentially mutating them. To switch back to the 163 * original untouched certificates, we need to force a collection pass. 164 */ 165 public static final int SIGNATURE_MALFORMED_RECOVER = 3; 166 } 167 168 private static final boolean DEBUG_STOPPED = false; 169 private static final boolean DEBUG_MU = false; 170 private static final boolean DEBUG_KERNEL = false; 171 private static final boolean DEBUG_PARSER = false; 172 173 private static final String RUNTIME_PERMISSIONS_FILE_NAME = "runtime-permissions.xml"; 174 175 private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage"; 176 private static final String ATTR_ENFORCEMENT = "enforcement"; 177 178 public static final String TAG_ITEM = "item"; 179 private static final String TAG_DISABLED_COMPONENTS = "disabled-components"; 180 private static final String TAG_ENABLED_COMPONENTS = "enabled-components"; 181 private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions"; 182 private static final String TAG_PACKAGE = "pkg"; 183 private static final String TAG_SHARED_USER = "shared-user"; 184 private static final String TAG_RUNTIME_PERMISSIONS = "runtime-permissions"; 185 private static final String TAG_PERMISSIONS = "perms"; 186 private static final String TAG_CHILD_PACKAGE = "child-package"; 187 private static final String TAG_USES_STATIC_LIB = "uses-static-lib"; 188 private static final String TAG_BLOCK_UNINSTALL_PACKAGES = "block-uninstall-packages"; 189 private static final String TAG_BLOCK_UNINSTALL = "block-uninstall"; 190 191 private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES = 192 "persistent-preferred-activities"; 193 static final String TAG_CROSS_PROFILE_INTENT_FILTERS = 194 "crossProfile-intent-filters"; 195 private static final String TAG_DOMAIN_VERIFICATION = "domain-verification"; 196 private static final String TAG_DEFAULT_APPS = "default-apps"; 197 private static final String TAG_ALL_INTENT_FILTER_VERIFICATION = 198 "all-intent-filter-verifications"; 199 private static final String TAG_DEFAULT_BROWSER = "default-browser"; 200 private static final String TAG_DEFAULT_DIALER = "default-dialer"; 201 private static final String TAG_VERSION = "version"; 202 203 public static final String ATTR_NAME = "name"; 204 public static final String ATTR_PACKAGE = "package"; 205 private static final String ATTR_USER = "user"; 206 private static final String ATTR_CODE = "code"; 207 private static final String ATTR_GRANTED = "granted"; 208 private static final String ATTR_FLAGS = "flags"; 209 private static final String ATTR_VERSION = "version"; 210 211 private static final String ATTR_CE_DATA_INODE = "ceDataInode"; 212 private static final String ATTR_INSTALLED = "inst"; 213 private static final String ATTR_STOPPED = "stopped"; 214 private static final String ATTR_NOT_LAUNCHED = "nl"; 215 // Legacy, here for reading older versions of the package-restrictions. 216 private static final String ATTR_BLOCKED = "blocked"; 217 // New name for the above attribute. 218 private static final String ATTR_HIDDEN = "hidden"; 219 private static final String ATTR_SUSPENDED = "suspended"; 220 // Legacy, uninstall blocks are stored separately. 221 @Deprecated 222 private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall"; 223 private static final String ATTR_ENABLED = "enabled"; 224 private static final String ATTR_ENABLED_CALLER = "enabledCaller"; 225 private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus"; 226 private static final String ATTR_APP_LINK_GENERATION = "app-link-generation"; 227 private static final String ATTR_INSTALL_REASON = "install-reason"; 228 private static final String ATTR_INSTANT_APP = "instant-app"; 229 private static final String ATTR_VIRTUAL_PRELOAD = "virtual-preload"; 230 231 private static final String ATTR_PACKAGE_NAME = "packageName"; 232 private static final String ATTR_FINGERPRINT = "fingerprint"; 233 private static final String ATTR_VOLUME_UUID = "volumeUuid"; 234 private static final String ATTR_SDK_VERSION = "sdkVersion"; 235 private static final String ATTR_DATABASE_VERSION = "databaseVersion"; 236 237 // Bookkeeping for restored permission grants 238 private static final String TAG_RESTORED_RUNTIME_PERMISSIONS = "restored-perms"; 239 // package name: ATTR_PACKAGE_NAME 240 private static final String TAG_PERMISSION_ENTRY = "perm"; 241 // permission name: ATTR_NAME 242 // permission granted (boolean): ATTR_GRANTED 243 private static final String ATTR_USER_SET = "set"; 244 private static final String ATTR_USER_FIXED = "fixed"; 245 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 246 247 // Flag mask of restored permission grants that are applied at install time 248 private static final int USER_RUNTIME_GRANT_MASK = 249 FLAG_PERMISSION_USER_SET 250 | FLAG_PERMISSION_USER_FIXED 251 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 252 253 private final Object mLock; 254 255 private final RuntimePermissionPersistence mRuntimePermissionsPersistence; 256 257 private final File mSettingsFilename; 258 private final File mBackupSettingsFilename; 259 private final File mPackageListFilename; 260 private final File mStoppedPackagesFilename; 261 private final File mBackupStoppedPackagesFilename; 262 /** The top level directory in configfs for sdcardfs to push the package->uid,userId mappings */ 263 private final File mKernelMappingFilename; 264 265 /** Map from package name to settings */ 266 final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<>(); 267 268 /** List of packages that installed other packages */ 269 final ArraySet<String> mInstallerPackages = new ArraySet<>(); 270 271 /** Map from package name to appId and excluded userids */ 272 private final ArrayMap<String, KernelPackageState> mKernelMapping = new ArrayMap<>(); 273 274 // List of replaced system applications 275 private final ArrayMap<String, PackageSetting> mDisabledSysPackages = 276 new ArrayMap<String, PackageSetting>(); 277 278 /** List of packages that are blocked for uninstall for specific users */ 279 private final SparseArray<ArraySet<String>> mBlockUninstallPackages = new SparseArray<>(); 280 281 // Set of restored intent-filter verification states 282 private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications = 283 new ArrayMap<String, IntentFilterVerificationInfo>(); 284 285 private static final class KernelPackageState { 286 int appId; 287 int[] excludedUserIds; 288 } 289 290 // Bookkeeping for restored user permission grants 291 final class RestoredPermissionGrant { 292 String permissionName; 293 boolean granted; 294 int grantBits; 295 296 RestoredPermissionGrant(String name, boolean isGranted, int theGrantBits) { 297 permissionName = name; 298 granted = isGranted; 299 grantBits = theGrantBits; 300 } 301 } 302 303 // This would be more compact as a flat array of restored grants or something, but we 304 // may have quite a few, especially during early device lifetime, and avoiding all those 305 // linear lookups will be important. 306 private final SparseArray<ArrayMap<String, ArraySet<RestoredPermissionGrant>>> 307 mRestoredUserGrants = 308 new SparseArray<ArrayMap<String, ArraySet<RestoredPermissionGrant>>>(); 309 310 private static int mFirstAvailableUid = 0; 311 312 /** Map from volume UUID to {@link VersionInfo} */ 313 private ArrayMap<String, VersionInfo> mVersion = new ArrayMap<>(); 314 315 /** 316 * Version details for a storage volume that may hold apps. 317 */ 318 public static class VersionInfo { 319 /** 320 * These are the last platform API version we were using for the apps 321 * installed on internal and external storage. It is used to grant newer 322 * permissions one time during a system upgrade. 323 */ 324 int sdkVersion; 325 326 /** 327 * The current database version for apps on internal storage. This is 328 * used to upgrade the format of the packages.xml database not 329 * necessarily tied to an SDK version. 330 */ 331 int databaseVersion; 332 333 /** 334 * Last known value of {@link Build#FINGERPRINT}. Used to determine when 335 * an system update has occurred, meaning we need to clear code caches. 336 */ 337 String fingerprint; 338 339 /** 340 * Force all version information to match current system values, 341 * typically after resolving any required upgrade steps. 342 */ 343 public void forceCurrent() { 344 sdkVersion = Build.VERSION.SDK_INT; 345 databaseVersion = CURRENT_DATABASE_VERSION; 346 fingerprint = Build.FINGERPRINT; 347 } 348 } 349 350 Boolean mReadExternalStorageEnforced; 351 352 /** Device identity for the purpose of package verification. */ 353 private VerifierDeviceIdentity mVerifierDeviceIdentity; 354 355 // The user's preferred activities associated with particular intent 356 // filters. 357 final SparseArray<PreferredIntentResolver> mPreferredActivities = 358 new SparseArray<PreferredIntentResolver>(); 359 360 // The persistent preferred activities of the user's profile/device owner 361 // associated with particular intent filters. 362 final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities = 363 new SparseArray<PersistentPreferredIntentResolver>(); 364 365 // For every user, it is used to find to which other users the intent can be forwarded. 366 final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers = 367 new SparseArray<CrossProfileIntentResolver>(); 368 369 final ArrayMap<String, SharedUserSetting> mSharedUsers = 370 new ArrayMap<String, SharedUserSetting>(); 371 private final ArrayList<Object> mUserIds = new ArrayList<Object>(); 372 private final SparseArray<Object> mOtherUserIds = 373 new SparseArray<Object>(); 374 375 // For reading/writing settings file. 376 private final ArrayList<Signature> mPastSignatures = 377 new ArrayList<Signature>(); 378 private final ArrayMap<Long, Integer> mKeySetRefs = 379 new ArrayMap<Long, Integer>(); 380 381 // Packages that have been uninstalled and still need their external 382 // storage data deleted. 383 final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>(); 384 385 // Packages that have been renamed since they were first installed. 386 // Keys are the new names of the packages, values are the original 387 // names. The packages appear everywhere else under their original 388 // names. 389 private final ArrayMap<String, String> mRenamedPackages = new ArrayMap<String, String>(); 390 391 // For every user, it is used to find the package name of the default Browser App. 392 final SparseArray<String> mDefaultBrowserApp = new SparseArray<String>(); 393 394 // For every user, a record of the package name of the default Dialer App. 395 final SparseArray<String> mDefaultDialerApp = new SparseArray<String>(); 396 397 // App-link priority tracking, per-user 398 final SparseIntArray mNextAppLinkGeneration = new SparseIntArray(); 399 400 final StringBuilder mReadMessages = new StringBuilder(); 401 402 /** 403 * Used to track packages that have a shared user ID that hasn't been read 404 * in yet. 405 * <p> 406 * TODO: make this just a local variable that is passed in during package 407 * scanning to make it less confusing. 408 */ 409 private final ArrayList<PackageSetting> mPendingPackages = new ArrayList<>(); 410 411 private final File mSystemDir; 412 413 public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages); 414 /** Settings and other information about permissions */ 415 final PermissionSettings mPermissions; 416 417 Settings(PermissionSettings permissions, Object lock) { 418 this(Environment.getDataDirectory(), permissions, lock); 419 } 420 421 Settings(File dataDir, PermissionSettings permission, Object lock) { 422 mLock = lock; 423 mPermissions = permission; 424 mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock); 425 426 mSystemDir = new File(dataDir, "system"); 427 mSystemDir.mkdirs(); 428 FileUtils.setPermissions(mSystemDir.toString(), 429 FileUtils.S_IRWXU|FileUtils.S_IRWXG 430 |FileUtils.S_IROTH|FileUtils.S_IXOTH, 431 -1, -1); 432 mSettingsFilename = new File(mSystemDir, "packages.xml"); 433 mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); 434 mPackageListFilename = new File(mSystemDir, "packages.list"); 435 FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID); 436 437 final File kernelDir = new File("/config/sdcardfs"); 438 mKernelMappingFilename = kernelDir.exists() ? kernelDir : null; 439 440 // Deprecated: Needed for migration 441 mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml"); 442 mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); 443 } 444 445 PackageSetting getPackageLPr(String pkgName) { 446 return mPackages.get(pkgName); 447 } 448 449 String getRenamedPackageLPr(String pkgName) { 450 return mRenamedPackages.get(pkgName); 451 } 452 453 String addRenamedPackageLPw(String pkgName, String origPkgName) { 454 return mRenamedPackages.put(pkgName, origPkgName); 455 } 456 457 void setInstallStatus(String pkgName, final int status) { 458 PackageSetting p = mPackages.get(pkgName); 459 if(p != null) { 460 if(p.getInstallStatus() != status) { 461 p.setInstallStatus(status); 462 } 463 } 464 } 465 466 void applyPendingPermissionGrantsLPw(String packageName, int userId) { 467 ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage = 468 mRestoredUserGrants.get(userId); 469 if (grantsByPackage == null || grantsByPackage.size() == 0) { 470 return; 471 } 472 473 ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(packageName); 474 if (grants == null || grants.size() == 0) { 475 return; 476 } 477 478 final PackageSetting ps = mPackages.get(packageName); 479 if (ps == null) { 480 Slog.e(TAG, "Can't find supposedly installed package " + packageName); 481 return; 482 } 483 final PermissionsState perms = ps.getPermissionsState(); 484 485 for (RestoredPermissionGrant grant : grants) { 486 BasePermission bp = mPermissions.getPermission(grant.permissionName); 487 if (bp != null) { 488 if (grant.granted) { 489 perms.grantRuntimePermission(bp, userId); 490 } 491 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, grant.grantBits); 492 } 493 } 494 495 // And remove it from the pending-grant bookkeeping 496 grantsByPackage.remove(packageName); 497 if (grantsByPackage.size() < 1) { 498 mRestoredUserGrants.remove(userId); 499 } 500 writeRuntimePermissionsForUserLPr(userId, false); 501 } 502 503 public boolean canPropagatePermissionToInstantApp(String permName) { 504 return mPermissions.canPropagatePermissionToInstantApp(permName); 505 } 506 507 void setInstallerPackageName(String pkgName, String installerPkgName) { 508 PackageSetting p = mPackages.get(pkgName); 509 if (p != null) { 510 p.setInstallerPackageName(installerPkgName); 511 if (installerPkgName != null) { 512 mInstallerPackages.add(installerPkgName); 513 } 514 } 515 } 516 517 /** Gets and optionally creates a new shared user id. */ 518 SharedUserSetting getSharedUserLPw(String name, int pkgFlags, int pkgPrivateFlags, 519 boolean create) throws PackageManagerException { 520 SharedUserSetting s = mSharedUsers.get(name); 521 if (s == null && create) { 522 s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags); 523 s.userId = newUserIdLPw(s); 524 if (s.userId < 0) { 525 // < 0 means we couldn't assign a userid; throw exception 526 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 527 "Creating shared user " + name + " failed"); 528 } 529 Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId); 530 mSharedUsers.put(name, s); 531 } 532 return s; 533 } 534 535 Collection<SharedUserSetting> getAllSharedUsersLPw() { 536 return mSharedUsers.values(); 537 } 538 539 boolean disableSystemPackageLPw(String name, boolean replaced) { 540 final PackageSetting p = mPackages.get(name); 541 if(p == null) { 542 Log.w(PackageManagerService.TAG, "Package " + name + " is not an installed package"); 543 return false; 544 } 545 final PackageSetting dp = mDisabledSysPackages.get(name); 546 // always make sure the system package code and resource paths dont change 547 if (dp == null && p.pkg != null && p.pkg.isSystem() && !p.pkg.isUpdatedSystemApp()) { 548 if((p.pkg != null) && (p.pkg.applicationInfo != null)) { 549 p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 550 } 551 mDisabledSysPackages.put(name, p); 552 553 if (replaced) { 554 // a little trick... when we install the new package, we don't 555 // want to modify the existing PackageSetting for the built-in 556 // version. so at this point we need a new PackageSetting that 557 // is okay to muck with. 558 PackageSetting newp = new PackageSetting(p); 559 replacePackageLPw(name, newp); 560 } 561 return true; 562 } 563 return false; 564 } 565 566 PackageSetting enableSystemPackageLPw(String name) { 567 PackageSetting p = mDisabledSysPackages.get(name); 568 if(p == null) { 569 Log.w(PackageManagerService.TAG, "Package " + name + " is not disabled"); 570 return null; 571 } 572 // Reset flag in ApplicationInfo object 573 if((p.pkg != null) && (p.pkg.applicationInfo != null)) { 574 p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 575 } 576 PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath, 577 p.legacyNativeLibraryPathString, p.primaryCpuAbiString, 578 p.secondaryCpuAbiString, p.cpuAbiOverrideString, 579 p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags, 580 p.parentPackageName, p.childPackageNames, p.usesStaticLibraries, 581 p.usesStaticLibrariesVersions); 582 mDisabledSysPackages.remove(name); 583 return ret; 584 } 585 586 boolean isDisabledSystemPackageLPr(String name) { 587 return mDisabledSysPackages.containsKey(name); 588 } 589 590 void removeDisabledSystemPackageLPw(String name) { 591 mDisabledSysPackages.remove(name); 592 } 593 594 PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath, 595 String legacyNativeLibraryPathString, String primaryCpuAbiString, 596 String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int 597 pkgFlags, int pkgPrivateFlags, String parentPackageName, 598 List<String> childPackageNames, String[] usesStaticLibraries, 599 long[] usesStaticLibraryNames) { 600 PackageSetting p = mPackages.get(name); 601 if (p != null) { 602 if (p.appId == uid) { 603 return p; 604 } 605 PackageManagerService.reportSettingsProblem(Log.ERROR, 606 "Adding duplicate package, keeping first: " + name); 607 return null; 608 } 609 p = new PackageSetting(name, realName, codePath, resourcePath, 610 legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, 611 cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags, parentPackageName, 612 childPackageNames, 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames); 613 p.appId = uid; 614 if (addUserIdLPw(uid, p, name)) { 615 mPackages.put(name, p); 616 return p; 617 } 618 return null; 619 } 620 621 void addAppOpPackage(String permName, String packageName) { 622 mPermissions.addAppOpPackage(permName, packageName); 623 } 624 625 SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) { 626 SharedUserSetting s = mSharedUsers.get(name); 627 if (s != null) { 628 if (s.userId == uid) { 629 return s; 630 } 631 PackageManagerService.reportSettingsProblem(Log.ERROR, 632 "Adding duplicate shared user, keeping first: " + name); 633 return null; 634 } 635 s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags); 636 s.userId = uid; 637 if (addUserIdLPw(uid, s, name)) { 638 mSharedUsers.put(name, s); 639 return s; 640 } 641 return null; 642 } 643 644 void pruneSharedUsersLPw() { 645 ArrayList<String> removeStage = new ArrayList<String>(); 646 for (Map.Entry<String,SharedUserSetting> entry : mSharedUsers.entrySet()) { 647 final SharedUserSetting sus = entry.getValue(); 648 if (sus == null) { 649 removeStage.add(entry.getKey()); 650 continue; 651 } 652 // remove packages that are no longer installed 653 for (Iterator<PackageSetting> iter = sus.packages.iterator(); iter.hasNext();) { 654 PackageSetting ps = iter.next(); 655 if (mPackages.get(ps.name) == null) { 656 iter.remove(); 657 } 658 } 659 if (sus.packages.size() == 0) { 660 removeStage.add(entry.getKey()); 661 } 662 } 663 for (int i = 0; i < removeStage.size(); i++) { 664 mSharedUsers.remove(removeStage.get(i)); 665 } 666 } 667 668 /** 669 * Creates a new {@code PackageSetting} object. 670 * Use this method instead of the constructor to ensure a settings object is created 671 * with the correct base. 672 */ 673 static @NonNull PackageSetting createNewSetting(String pkgName, PackageSetting originalPkg, 674 PackageSetting disabledPkg, String realPkgName, SharedUserSetting sharedUser, 675 File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi, 676 String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags, 677 UserHandle installUser, boolean allowInstall, boolean instantApp, 678 boolean virtualPreload, String parentPkgName, List<String> childPkgNames, 679 UserManagerService userManager, 680 String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) { 681 final PackageSetting pkgSetting; 682 if (originalPkg != null) { 683 if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " 684 + pkgName + " is adopting original package " + originalPkg.name); 685 pkgSetting = new PackageSetting(originalPkg, pkgName /*realPkgName*/); 686 pkgSetting.childPackageNames = 687 (childPkgNames != null) ? new ArrayList<>(childPkgNames) : null; 688 pkgSetting.codePath = codePath; 689 pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath; 690 pkgSetting.parentPackageName = parentPkgName; 691 pkgSetting.pkgFlags = pkgFlags; 692 pkgSetting.pkgPrivateFlags = pkgPrivateFlags; 693 pkgSetting.primaryCpuAbiString = primaryCpuAbi; 694 pkgSetting.resourcePath = resourcePath; 695 pkgSetting.secondaryCpuAbiString = secondaryCpuAbi; 696 // NOTE: Create a deeper copy of the package signatures so we don't 697 // overwrite the signatures in the original package setting. 698 pkgSetting.signatures = new PackageSignatures(); 699 pkgSetting.versionCode = versionCode; 700 pkgSetting.usesStaticLibraries = usesStaticLibraries; 701 pkgSetting.usesStaticLibrariesVersions = usesStaticLibrariesVersions; 702 // Update new package state. 703 pkgSetting.setTimeStamp(codePath.lastModified()); 704 } else { 705 pkgSetting = new PackageSetting(pkgName, realPkgName, codePath, resourcePath, 706 legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi, 707 null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags, 708 parentPkgName, childPkgNames, 0 /*sharedUserId*/, usesStaticLibraries, 709 usesStaticLibrariesVersions); 710 pkgSetting.setTimeStamp(codePath.lastModified()); 711 pkgSetting.sharedUser = sharedUser; 712 // If this is not a system app, it starts out stopped. 713 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 714 if (DEBUG_STOPPED) { 715 RuntimeException e = new RuntimeException("here"); 716 e.fillInStackTrace(); 717 Slog.i(PackageManagerService.TAG, "Stopping package " + pkgName, e); 718 } 719 List<UserInfo> users = getAllUsers(userManager); 720 final int installUserId = installUser != null ? installUser.getIdentifier() : 0; 721 if (users != null && allowInstall) { 722 for (UserInfo user : users) { 723 // By default we consider this app to be installed 724 // for the user if no user has been specified (which 725 // means to leave it at its original value, and the 726 // original default value is true), or we are being 727 // asked to install for all users, or this is the 728 // user we are installing for. 729 final boolean installed = installUser == null 730 || (installUserId == UserHandle.USER_ALL 731 && !isAdbInstallDisallowed(userManager, user.id)) 732 || installUserId == user.id; 733 pkgSetting.setUserState(user.id, 0, COMPONENT_ENABLED_STATE_DEFAULT, 734 installed, 735 true /*stopped*/, 736 true /*notLaunched*/, 737 false /*hidden*/, 738 false /*suspended*/, 739 instantApp, 740 virtualPreload, 741 null /*lastDisableAppCaller*/, 742 null /*enabledComponents*/, 743 null /*disabledComponents*/, 744 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 745 0, PackageManager.INSTALL_REASON_UNKNOWN); 746 } 747 } 748 } 749 if (sharedUser != null) { 750 pkgSetting.appId = sharedUser.userId; 751 } else { 752 // Clone the setting here for disabled system packages 753 if (disabledPkg != null) { 754 // For disabled packages a new setting is created 755 // from the existing user id. This still has to be 756 // added to list of user id's 757 // Copy signatures from previous setting 758 pkgSetting.signatures = new PackageSignatures(disabledPkg.signatures); 759 pkgSetting.appId = disabledPkg.appId; 760 // Clone permissions 761 pkgSetting.getPermissionsState().copyFrom(disabledPkg.getPermissionsState()); 762 // Clone component info 763 List<UserInfo> users = getAllUsers(userManager); 764 if (users != null) { 765 for (UserInfo user : users) { 766 final int userId = user.id; 767 pkgSetting.setDisabledComponentsCopy( 768 disabledPkg.getDisabledComponents(userId), userId); 769 pkgSetting.setEnabledComponentsCopy( 770 disabledPkg.getEnabledComponents(userId), userId); 771 } 772 } 773 } 774 } 775 } 776 return pkgSetting; 777 } 778 779 /** 780 * Updates the given package setting using the provided information. 781 * <p> 782 * WARNING: The provided PackageSetting object may be mutated. 783 */ 784 static void updatePackageSetting(@NonNull PackageSetting pkgSetting, 785 @Nullable PackageSetting disabledPkg, @Nullable SharedUserSetting sharedUser, 786 @NonNull File codePath, File resourcePath, 787 @Nullable String legacyNativeLibraryPath, @Nullable String primaryCpuAbi, 788 @Nullable String secondaryCpuAbi, int pkgFlags, int pkgPrivateFlags, 789 @Nullable List<String> childPkgNames, @NonNull UserManagerService userManager, 790 @Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions) 791 throws PackageManagerException { 792 final String pkgName = pkgSetting.name; 793 if (pkgSetting.sharedUser != sharedUser) { 794 PackageManagerService.reportSettingsProblem(Log.WARN, 795 "Package " + pkgName + " shared user changed from " 796 + (pkgSetting.sharedUser != null ? pkgSetting.sharedUser.name : "<nothing>") 797 + " to " + (sharedUser != null ? sharedUser.name : "<nothing>")); 798 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 799 "Updating application package " + pkgName + " failed"); 800 } 801 802 if (!pkgSetting.codePath.equals(codePath)) { 803 final boolean isSystem = pkgSetting.isSystem(); 804 Slog.i(PackageManagerService.TAG, 805 "Update" + (isSystem ? " system" : "") 806 + " package " + pkgName 807 + " code path from " + pkgSetting.codePathString 808 + " to " + codePath.toString() 809 + "; Retain data and using new"); 810 if (!isSystem) { 811 // The package isn't considered as installed if the application was 812 // first installed by another user. Update the installed flag when the 813 // application ever becomes part of the system. 814 if ((pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0 && disabledPkg == null) { 815 final List<UserInfo> allUserInfos = getAllUsers(userManager); 816 if (allUserInfos != null) { 817 for (UserInfo userInfo : allUserInfos) { 818 pkgSetting.setInstalled(true, userInfo.id); 819 } 820 } 821 } 822 823 // Since we've changed paths, prefer the new native library path over 824 // the one stored in the package settings since we might have moved from 825 // internal to external storage or vice versa. 826 pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath; 827 } 828 pkgSetting.codePath = codePath; 829 pkgSetting.codePathString = codePath.toString(); 830 } 831 if (!pkgSetting.resourcePath.equals(resourcePath)) { 832 final boolean isSystem = pkgSetting.isSystem(); 833 Slog.i(PackageManagerService.TAG, 834 "Update" + (isSystem ? " system" : "") 835 + " package " + pkgName 836 + " resource path from " + pkgSetting.resourcePathString 837 + " to " + resourcePath.toString() 838 + "; Retain data and using new"); 839 pkgSetting.resourcePath = resourcePath; 840 pkgSetting.resourcePathString = resourcePath.toString(); 841 } 842 // If what we are scanning is a system (and possibly privileged) package, 843 // then make it so, regardless of whether it was previously installed only 844 // in the data partition. 845 pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM; 846 pkgSetting.pkgPrivateFlags |= 847 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 848 pkgSetting.pkgPrivateFlags |= 849 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM; 850 pkgSetting.pkgPrivateFlags |= 851 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR; 852 pkgSetting.primaryCpuAbiString = primaryCpuAbi; 853 pkgSetting.secondaryCpuAbiString = secondaryCpuAbi; 854 if (childPkgNames != null) { 855 pkgSetting.childPackageNames = new ArrayList<>(childPkgNames); 856 } 857 // Update static shared library dependencies if needed 858 if (usesStaticLibraries != null && usesStaticLibrariesVersions != null 859 && usesStaticLibraries.length == usesStaticLibrariesVersions.length) { 860 pkgSetting.usesStaticLibraries = usesStaticLibraries; 861 pkgSetting.usesStaticLibrariesVersions = usesStaticLibrariesVersions; 862 } else { 863 pkgSetting.usesStaticLibraries = null; 864 pkgSetting.usesStaticLibrariesVersions = null; 865 } 866 } 867 868 /** 869 * Registers a user ID with the system. Potentially allocates a new user ID. 870 * @throws PackageManagerException If a user ID could not be allocated. 871 */ 872 void addUserToSettingLPw(PackageSetting p) throws PackageManagerException { 873 if (p.appId == 0) { 874 // Assign new user ID 875 p.appId = newUserIdLPw(p); 876 } else { 877 // Add new setting to list of user IDs 878 addUserIdLPw(p.appId, p, p.name); 879 } 880 if (p.appId < 0) { 881 PackageManagerService.reportSettingsProblem(Log.WARN, 882 "Package " + p.name + " could not be assigned a valid UID"); 883 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 884 "Package " + p.name + " could not be assigned a valid UID"); 885 } 886 } 887 888 /** 889 * Writes per-user package restrictions if the user state has changed. If the user 890 * state has not changed, this does nothing. 891 */ 892 void writeUserRestrictionsLPw(PackageSetting newPackage, PackageSetting oldPackage) { 893 // package doesn't exist; do nothing 894 if (getPackageLPr(newPackage.name) == null) { 895 return; 896 } 897 // no users defined; do nothing 898 final List<UserInfo> allUsers = getAllUsers(UserManagerService.getInstance()); 899 if (allUsers == null) { 900 return; 901 } 902 for (UserInfo user : allUsers) { 903 final PackageUserState oldUserState = oldPackage == null 904 ? PackageSettingBase.DEFAULT_USER_STATE 905 : oldPackage.readUserState(user.id); 906 if (!oldUserState.equals(newPackage.readUserState(user.id))) { 907 writePackageRestrictionsLPr(user.id); 908 } 909 } 910 } 911 912 static boolean isAdbInstallDisallowed(UserManagerService userManager, int userId) { 913 return userManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 914 userId); 915 } 916 917 // TODO: Move to scanPackageOnlyLI() after verifying signatures are setup correctly 918 // by that time. 919 void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) { 920 // Update signatures if needed. 921 if (p.signatures.mSignatures == null) { 922 p.signatures.assignSignatures(pkg.mSigningDetails); 923 } 924 // If this app defines a shared user id initialize 925 // the shared user signatures as well. 926 if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) { 927 p.sharedUser.signatures.assignSignatures(pkg.mSigningDetails); 928 } 929 addPackageSettingLPw(p, p.sharedUser); 930 } 931 932 // Utility method that adds a PackageSetting to mPackages and 933 // completes updating the shared user attributes and any restored 934 // app link verification state 935 private void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) { 936 mPackages.put(p.name, p); 937 if (sharedUser != null) { 938 if (p.sharedUser != null && p.sharedUser != sharedUser) { 939 PackageManagerService.reportSettingsProblem(Log.ERROR, 940 "Package " + p.name + " was user " 941 + p.sharedUser + " but is now " + sharedUser 942 + "; I am not changing its files so it will probably fail!"); 943 p.sharedUser.removePackage(p); 944 } else if (p.appId != sharedUser.userId) { 945 PackageManagerService.reportSettingsProblem(Log.ERROR, 946 "Package " + p.name + " was user id " + p.appId 947 + " but is now user " + sharedUser 948 + " with id " + sharedUser.userId 949 + "; I am not changing its files so it will probably fail!"); 950 } 951 952 sharedUser.addPackage(p); 953 p.sharedUser = sharedUser; 954 p.appId = sharedUser.userId; 955 } 956 957 // If the we know about this user id, we have to update it as it 958 // has to point to the same PackageSetting instance as the package. 959 Object userIdPs = getUserIdLPr(p.appId); 960 if (sharedUser == null) { 961 if (userIdPs != null && userIdPs != p) { 962 replaceUserIdLPw(p.appId, p); 963 } 964 } else { 965 if (userIdPs != null && userIdPs != sharedUser) { 966 replaceUserIdLPw(p.appId, sharedUser); 967 } 968 } 969 970 IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(p.name); 971 if (ivi != null) { 972 if (DEBUG_DOMAIN_VERIFICATION) { 973 Slog.i(TAG, "Applying restored IVI for " + p.name + " : " + ivi.getStatusString()); 974 } 975 mRestoredIntentFilterVerifications.remove(p.name); 976 p.setIntentFilterVerificationInfo(ivi); 977 } 978 } 979 980 /* 981 * Update the shared user setting when a package using 982 * specifying the shared user id is removed. The gids 983 * associated with each permission of the deleted package 984 * are removed from the shared user's gid list only if its 985 * not in use by other permissions of packages in the 986 * shared user setting. 987 */ 988 int updateSharedUserPermsLPw(PackageSetting deletedPs, int userId) { 989 if ((deletedPs == null) || (deletedPs.pkg == null)) { 990 Slog.i(PackageManagerService.TAG, 991 "Trying to update info for null package. Just ignoring"); 992 return UserHandle.USER_NULL; 993 } 994 995 // No sharedUserId 996 if (deletedPs.sharedUser == null) { 997 return UserHandle.USER_NULL; 998 } 999 1000 SharedUserSetting sus = deletedPs.sharedUser; 1001 1002 // Update permissions 1003 for (String eachPerm : deletedPs.pkg.requestedPermissions) { 1004 BasePermission bp = mPermissions.getPermission(eachPerm); 1005 if (bp == null) { 1006 continue; 1007 } 1008 1009 // Check if another package in the shared user needs the permission. 1010 boolean used = false; 1011 for (PackageSetting pkg : sus.packages) { 1012 if (pkg.pkg != null 1013 && !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) 1014 && pkg.pkg.requestedPermissions.contains(eachPerm)) { 1015 used = true; 1016 break; 1017 } 1018 } 1019 if (used) { 1020 continue; 1021 } 1022 1023 PermissionsState permissionsState = sus.getPermissionsState(); 1024 PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.packageName); 1025 1026 // If the package is shadowing is a disabled system package, 1027 // do not drop permissions that the shadowed package requests. 1028 if (disabledPs != null) { 1029 boolean reqByDisabledSysPkg = false; 1030 for (String permission : disabledPs.pkg.requestedPermissions) { 1031 if (permission.equals(eachPerm)) { 1032 reqByDisabledSysPkg = true; 1033 break; 1034 } 1035 } 1036 if (reqByDisabledSysPkg) { 1037 continue; 1038 } 1039 } 1040 1041 // Try to revoke as an install permission which is for all users. 1042 // The package is gone - no need to keep flags for applying policy. 1043 permissionsState.updatePermissionFlags(bp, userId, 1044 PackageManager.MASK_PERMISSION_FLAGS, 0); 1045 1046 if (permissionsState.revokeInstallPermission(bp) == 1047 PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) { 1048 return UserHandle.USER_ALL; 1049 } 1050 1051 // Try to revoke as an install permission which is per user. 1052 if (permissionsState.revokeRuntimePermission(bp, userId) == 1053 PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) { 1054 return userId; 1055 } 1056 } 1057 1058 return UserHandle.USER_NULL; 1059 } 1060 1061 int removePackageLPw(String name) { 1062 final PackageSetting p = mPackages.get(name); 1063 if (p != null) { 1064 mPackages.remove(name); 1065 removeInstallerPackageStatus(name); 1066 if (p.sharedUser != null) { 1067 p.sharedUser.removePackage(p); 1068 if (p.sharedUser.packages.size() == 0) { 1069 mSharedUsers.remove(p.sharedUser.name); 1070 removeUserIdLPw(p.sharedUser.userId); 1071 return p.sharedUser.userId; 1072 } 1073 } else { 1074 removeUserIdLPw(p.appId); 1075 return p.appId; 1076 } 1077 } 1078 return -1; 1079 } 1080 1081 /** 1082 * Checks if {@param packageName} is an installer package and if so, clear the installer 1083 * package name of the packages that are installed by this. 1084 */ 1085 private void removeInstallerPackageStatus(String packageName) { 1086 // Check if the package to be removed is an installer package. 1087 if (!mInstallerPackages.contains(packageName)) { 1088 return; 1089 } 1090 for (int i = 0; i < mPackages.size(); i++) { 1091 final PackageSetting ps = mPackages.valueAt(i); 1092 final String installerPackageName = ps.getInstallerPackageName(); 1093 if (installerPackageName != null 1094 && installerPackageName.equals(packageName)) { 1095 ps.setInstallerPackageName(null); 1096 ps.isOrphaned = true; 1097 } 1098 } 1099 mInstallerPackages.remove(packageName); 1100 } 1101 1102 private void replacePackageLPw(String name, PackageSetting newp) { 1103 final PackageSetting p = mPackages.get(name); 1104 if (p != null) { 1105 if (p.sharedUser != null) { 1106 p.sharedUser.removePackage(p); 1107 p.sharedUser.addPackage(newp); 1108 } else { 1109 replaceUserIdLPw(p.appId, newp); 1110 } 1111 } 1112 mPackages.put(name, newp); 1113 } 1114 1115 private boolean addUserIdLPw(int uid, Object obj, Object name) { 1116 if (uid > Process.LAST_APPLICATION_UID) { 1117 return false; 1118 } 1119 1120 if (uid >= Process.FIRST_APPLICATION_UID) { 1121 int N = mUserIds.size(); 1122 final int index = uid - Process.FIRST_APPLICATION_UID; 1123 while (index >= N) { 1124 mUserIds.add(null); 1125 N++; 1126 } 1127 if (mUserIds.get(index) != null) { 1128 PackageManagerService.reportSettingsProblem(Log.ERROR, 1129 "Adding duplicate user id: " + uid 1130 + " name=" + name); 1131 return false; 1132 } 1133 mUserIds.set(index, obj); 1134 } else { 1135 if (mOtherUserIds.get(uid) != null) { 1136 PackageManagerService.reportSettingsProblem(Log.ERROR, 1137 "Adding duplicate shared id: " + uid 1138 + " name=" + name); 1139 return false; 1140 } 1141 mOtherUserIds.put(uid, obj); 1142 } 1143 return true; 1144 } 1145 1146 public Object getUserIdLPr(int uid) { 1147 if (uid >= Process.FIRST_APPLICATION_UID) { 1148 final int N = mUserIds.size(); 1149 final int index = uid - Process.FIRST_APPLICATION_UID; 1150 return index < N ? mUserIds.get(index) : null; 1151 } else { 1152 return mOtherUserIds.get(uid); 1153 } 1154 } 1155 1156 private void removeUserIdLPw(int uid) { 1157 if (uid >= Process.FIRST_APPLICATION_UID) { 1158 final int N = mUserIds.size(); 1159 final int index = uid - Process.FIRST_APPLICATION_UID; 1160 if (index < N) mUserIds.set(index, null); 1161 } else { 1162 mOtherUserIds.remove(uid); 1163 } 1164 setFirstAvailableUid(uid+1); 1165 } 1166 1167 private void replaceUserIdLPw(int uid, Object obj) { 1168 if (uid >= Process.FIRST_APPLICATION_UID) { 1169 final int N = mUserIds.size(); 1170 final int index = uid - Process.FIRST_APPLICATION_UID; 1171 if (index < N) mUserIds.set(index, obj); 1172 } else { 1173 mOtherUserIds.put(uid, obj); 1174 } 1175 } 1176 1177 PreferredIntentResolver editPreferredActivitiesLPw(int userId) { 1178 PreferredIntentResolver pir = mPreferredActivities.get(userId); 1179 if (pir == null) { 1180 pir = new PreferredIntentResolver(); 1181 mPreferredActivities.put(userId, pir); 1182 } 1183 return pir; 1184 } 1185 1186 PersistentPreferredIntentResolver editPersistentPreferredActivitiesLPw(int userId) { 1187 PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId); 1188 if (ppir == null) { 1189 ppir = new PersistentPreferredIntentResolver(); 1190 mPersistentPreferredActivities.put(userId, ppir); 1191 } 1192 return ppir; 1193 } 1194 1195 CrossProfileIntentResolver editCrossProfileIntentResolverLPw(int userId) { 1196 CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId); 1197 if (cpir == null) { 1198 cpir = new CrossProfileIntentResolver(); 1199 mCrossProfileIntentResolvers.put(userId, cpir); 1200 } 1201 return cpir; 1202 } 1203 1204 /** 1205 * The following functions suppose that you have a lock for managing access to the 1206 * mIntentFiltersVerifications map. 1207 */ 1208 1209 /* package protected */ 1210 IntentFilterVerificationInfo getIntentFilterVerificationLPr(String packageName) { 1211 PackageSetting ps = mPackages.get(packageName); 1212 if (ps == null) { 1213 if (DEBUG_DOMAIN_VERIFICATION) { 1214 Slog.w(PackageManagerService.TAG, "No package known: " + packageName); 1215 } 1216 return null; 1217 } 1218 return ps.getIntentFilterVerificationInfo(); 1219 } 1220 1221 /* package protected */ 1222 IntentFilterVerificationInfo createIntentFilterVerificationIfNeededLPw(String packageName, 1223 ArraySet<String> domains) { 1224 PackageSetting ps = mPackages.get(packageName); 1225 if (ps == null) { 1226 if (DEBUG_DOMAIN_VERIFICATION) { 1227 Slog.w(PackageManagerService.TAG, "No package known: " + packageName); 1228 } 1229 return null; 1230 } 1231 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 1232 if (ivi == null) { 1233 ivi = new IntentFilterVerificationInfo(packageName, domains); 1234 ps.setIntentFilterVerificationInfo(ivi); 1235 if (DEBUG_DOMAIN_VERIFICATION) { 1236 Slog.d(PackageManagerService.TAG, 1237 "Creating new IntentFilterVerificationInfo for pkg: " + packageName); 1238 } 1239 } else { 1240 ivi.setDomains(domains); 1241 if (DEBUG_DOMAIN_VERIFICATION) { 1242 Slog.d(PackageManagerService.TAG, 1243 "Setting domains to existing IntentFilterVerificationInfo for pkg: " + 1244 packageName + " and with domains: " + ivi.getDomainsString()); 1245 } 1246 } 1247 return ivi; 1248 } 1249 1250 int getIntentFilterVerificationStatusLPr(String packageName, int userId) { 1251 PackageSetting ps = mPackages.get(packageName); 1252 if (ps == null) { 1253 if (DEBUG_DOMAIN_VERIFICATION) { 1254 Slog.w(PackageManagerService.TAG, "No package known: " + packageName); 1255 } 1256 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 1257 } 1258 return (int)(ps.getDomainVerificationStatusForUser(userId) >> 32); 1259 } 1260 1261 boolean updateIntentFilterVerificationStatusLPw(String packageName, final int status, int userId) { 1262 // Update the status for the current package 1263 PackageSetting current = mPackages.get(packageName); 1264 if (current == null) { 1265 if (DEBUG_DOMAIN_VERIFICATION) { 1266 Slog.w(PackageManagerService.TAG, "No package known: " + packageName); 1267 } 1268 return false; 1269 } 1270 1271 final int alwaysGeneration; 1272 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 1273 alwaysGeneration = mNextAppLinkGeneration.get(userId) + 1; 1274 mNextAppLinkGeneration.put(userId, alwaysGeneration); 1275 } else { 1276 alwaysGeneration = 0; 1277 } 1278 1279 current.setDomainVerificationStatusForUser(status, alwaysGeneration, userId); 1280 return true; 1281 } 1282 1283 /** 1284 * Used for Settings App and PackageManagerService dump. Should be read only. 1285 */ 1286 List<IntentFilterVerificationInfo> getIntentFilterVerificationsLPr( 1287 String packageName) { 1288 if (packageName == null) { 1289 return Collections.<IntentFilterVerificationInfo>emptyList(); 1290 } 1291 ArrayList<IntentFilterVerificationInfo> result = new ArrayList<>(); 1292 for (PackageSetting ps : mPackages.values()) { 1293 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 1294 if (ivi == null || TextUtils.isEmpty(ivi.getPackageName()) || 1295 !ivi.getPackageName().equalsIgnoreCase(packageName)) { 1296 continue; 1297 } 1298 result.add(ivi); 1299 } 1300 return result; 1301 } 1302 1303 boolean removeIntentFilterVerificationLPw(String packageName, int userId) { 1304 PackageSetting ps = mPackages.get(packageName); 1305 if (ps == null) { 1306 if (DEBUG_DOMAIN_VERIFICATION) { 1307 Slog.w(PackageManagerService.TAG, "No package known: " + packageName); 1308 } 1309 return false; 1310 } 1311 ps.clearDomainVerificationStatusForUser(userId); 1312 return true; 1313 } 1314 1315 boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) { 1316 boolean result = false; 1317 for (int userId : userIds) { 1318 result |= removeIntentFilterVerificationLPw(packageName, userId); 1319 } 1320 return result; 1321 } 1322 1323 boolean setDefaultBrowserPackageNameLPw(String packageName, int userId) { 1324 if (userId == UserHandle.USER_ALL) { 1325 return false; 1326 } 1327 if (packageName != null) { 1328 mDefaultBrowserApp.put(userId, packageName); 1329 } else { 1330 mDefaultBrowserApp.remove(userId); 1331 } 1332 writePackageRestrictionsLPr(userId); 1333 return true; 1334 } 1335 1336 String getDefaultBrowserPackageNameLPw(int userId) { 1337 return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.get(userId); 1338 } 1339 1340 boolean setDefaultDialerPackageNameLPw(String packageName, int userId) { 1341 if (userId == UserHandle.USER_ALL) { 1342 return false; 1343 } 1344 mDefaultDialerApp.put(userId, packageName); 1345 writePackageRestrictionsLPr(userId); 1346 return true; 1347 } 1348 1349 String getDefaultDialerPackageNameLPw(int userId) { 1350 return (userId == UserHandle.USER_ALL) ? null : mDefaultDialerApp.get(userId); 1351 } 1352 1353 private File getUserPackagesStateFile(int userId) { 1354 // TODO: Implement a cleaner solution when adding tests. 1355 // This instead of Environment.getUserSystemDirectory(userId) to support testing. 1356 File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId)); 1357 return new File(userDir, "package-restrictions.xml"); 1358 } 1359 1360 private File getUserRuntimePermissionsFile(int userId) { 1361 // TODO: Implement a cleaner solution when adding tests. 1362 // This instead of Environment.getUserSystemDirectory(userId) to support testing. 1363 File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId)); 1364 return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME); 1365 } 1366 1367 private File getUserPackagesStateBackupFile(int userId) { 1368 return new File(Environment.getUserSystemDirectory(userId), 1369 "package-restrictions-backup.xml"); 1370 } 1371 1372 void writeAllUsersPackageRestrictionsLPr() { 1373 List<UserInfo> users = getAllUsers(UserManagerService.getInstance()); 1374 if (users == null) return; 1375 1376 for (UserInfo user : users) { 1377 writePackageRestrictionsLPr(user.id); 1378 } 1379 } 1380 1381 void writeAllRuntimePermissionsLPr() { 1382 for (int userId : UserManagerService.getInstance().getUserIds()) { 1383 mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId); 1384 } 1385 } 1386 1387 boolean areDefaultRuntimePermissionsGrantedLPr(int userId) { 1388 return mRuntimePermissionsPersistence 1389 .areDefaultRuntimPermissionsGrantedLPr(userId); 1390 } 1391 1392 void onDefaultRuntimePermissionsGrantedLPr(int userId) { 1393 mRuntimePermissionsPersistence 1394 .onDefaultRuntimePermissionsGrantedLPr(userId); 1395 } 1396 1397 public VersionInfo findOrCreateVersion(String volumeUuid) { 1398 VersionInfo ver = mVersion.get(volumeUuid); 1399 if (ver == null) { 1400 ver = new VersionInfo(); 1401 mVersion.put(volumeUuid, ver); 1402 } 1403 return ver; 1404 } 1405 1406 public VersionInfo getInternalVersion() { 1407 return mVersion.get(StorageManager.UUID_PRIVATE_INTERNAL); 1408 } 1409 1410 public VersionInfo getExternalVersion() { 1411 return mVersion.get(StorageManager.UUID_PRIMARY_PHYSICAL); 1412 } 1413 1414 public void onVolumeForgotten(String fsUuid) { 1415 mVersion.remove(fsUuid); 1416 } 1417 1418 /** 1419 * Applies the preferred activity state described by the given XML. This code 1420 * also supports the restore-from-backup code path. 1421 * 1422 * @see PreferredActivityBackupHelper 1423 */ 1424 void readPreferredActivitiesLPw(XmlPullParser parser, int userId) 1425 throws XmlPullParserException, IOException { 1426 int outerDepth = parser.getDepth(); 1427 int type; 1428 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1429 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1430 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1431 continue; 1432 } 1433 1434 String tagName = parser.getName(); 1435 if (tagName.equals(TAG_ITEM)) { 1436 PreferredActivity pa = new PreferredActivity(parser); 1437 if (pa.mPref.getParseError() == null) { 1438 editPreferredActivitiesLPw(userId).addFilter(pa); 1439 } else { 1440 PackageManagerService.reportSettingsProblem(Log.WARN, 1441 "Error in package manager settings: <preferred-activity> " 1442 + pa.mPref.getParseError() + " at " 1443 + parser.getPositionDescription()); 1444 } 1445 } else { 1446 PackageManagerService.reportSettingsProblem(Log.WARN, 1447 "Unknown element under <preferred-activities>: " + parser.getName()); 1448 XmlUtils.skipCurrentTag(parser); 1449 } 1450 } 1451 } 1452 1453 private void readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId) 1454 throws XmlPullParserException, IOException { 1455 int outerDepth = parser.getDepth(); 1456 int type; 1457 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1458 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1459 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1460 continue; 1461 } 1462 String tagName = parser.getName(); 1463 if (tagName.equals(TAG_ITEM)) { 1464 PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser); 1465 editPersistentPreferredActivitiesLPw(userId).addFilter(ppa); 1466 } else { 1467 PackageManagerService.reportSettingsProblem(Log.WARN, 1468 "Unknown element under <" + TAG_PERSISTENT_PREFERRED_ACTIVITIES + ">: " 1469 + parser.getName()); 1470 XmlUtils.skipCurrentTag(parser); 1471 } 1472 } 1473 } 1474 1475 private void readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId) 1476 throws XmlPullParserException, IOException { 1477 int outerDepth = parser.getDepth(); 1478 int type; 1479 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1480 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1481 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1482 continue; 1483 } 1484 final String tagName = parser.getName(); 1485 if (tagName.equals(TAG_ITEM)) { 1486 CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser); 1487 editCrossProfileIntentResolverLPw(userId).addFilter(cpif); 1488 } else { 1489 String msg = "Unknown element under " + TAG_CROSS_PROFILE_INTENT_FILTERS + ": " + 1490 tagName; 1491 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 1492 XmlUtils.skipCurrentTag(parser); 1493 } 1494 } 1495 } 1496 1497 private void readDomainVerificationLPw(XmlPullParser parser, PackageSettingBase packageSetting) 1498 throws XmlPullParserException, IOException { 1499 IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser); 1500 packageSetting.setIntentFilterVerificationInfo(ivi); 1501 if (DEBUG_PARSER) { 1502 Log.d(TAG, "Read domain verification for package: " + ivi.getPackageName()); 1503 } 1504 } 1505 1506 private void readRestoredIntentFilterVerifications(XmlPullParser parser) 1507 throws XmlPullParserException, IOException { 1508 int outerDepth = parser.getDepth(); 1509 int type; 1510 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1511 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1512 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1513 continue; 1514 } 1515 final String tagName = parser.getName(); 1516 if (tagName.equals(TAG_DOMAIN_VERIFICATION)) { 1517 IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser); 1518 if (DEBUG_DOMAIN_VERIFICATION) { 1519 Slog.i(TAG, "Restored IVI for " + ivi.getPackageName() 1520 + " status=" + ivi.getStatusString()); 1521 } 1522 mRestoredIntentFilterVerifications.put(ivi.getPackageName(), ivi); 1523 } else { 1524 Slog.w(TAG, "Unknown element: " + tagName); 1525 XmlUtils.skipCurrentTag(parser); 1526 } 1527 } 1528 } 1529 1530 void readDefaultAppsLPw(XmlPullParser parser, int userId) 1531 throws XmlPullParserException, IOException { 1532 int outerDepth = parser.getDepth(); 1533 int type; 1534 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1535 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1536 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1537 continue; 1538 } 1539 String tagName = parser.getName(); 1540 if (tagName.equals(TAG_DEFAULT_BROWSER)) { 1541 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 1542 mDefaultBrowserApp.put(userId, packageName); 1543 } else if (tagName.equals(TAG_DEFAULT_DIALER)) { 1544 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 1545 mDefaultDialerApp.put(userId, packageName); 1546 } else { 1547 String msg = "Unknown element under " + TAG_DEFAULT_APPS + ": " + 1548 parser.getName(); 1549 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 1550 XmlUtils.skipCurrentTag(parser); 1551 } 1552 } 1553 } 1554 1555 void readBlockUninstallPackagesLPw(XmlPullParser parser, int userId) 1556 throws XmlPullParserException, IOException { 1557 int outerDepth = parser.getDepth(); 1558 int type; 1559 ArraySet<String> packages = new ArraySet<>(); 1560 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1561 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1562 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1563 continue; 1564 } 1565 String tagName = parser.getName(); 1566 if (tagName.equals(TAG_BLOCK_UNINSTALL)) { 1567 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 1568 packages.add(packageName); 1569 } else { 1570 String msg = "Unknown element under " + TAG_BLOCK_UNINSTALL_PACKAGES + ": " + 1571 parser.getName(); 1572 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 1573 XmlUtils.skipCurrentTag(parser); 1574 } 1575 } 1576 if (packages.isEmpty()) { 1577 mBlockUninstallPackages.remove(userId); 1578 } else { 1579 mBlockUninstallPackages.put(userId, packages); 1580 } 1581 } 1582 1583 void readPackageRestrictionsLPr(int userId) { 1584 if (DEBUG_MU) { 1585 Log.i(TAG, "Reading package restrictions for user=" + userId); 1586 } 1587 FileInputStream str = null; 1588 File userPackagesStateFile = getUserPackagesStateFile(userId); 1589 File backupFile = getUserPackagesStateBackupFile(userId); 1590 if (backupFile.exists()) { 1591 try { 1592 str = new FileInputStream(backupFile); 1593 mReadMessages.append("Reading from backup stopped packages file\n"); 1594 PackageManagerService.reportSettingsProblem(Log.INFO, 1595 "Need to read from backup stopped packages file"); 1596 if (userPackagesStateFile.exists()) { 1597 // If both the backup and normal file exist, we 1598 // ignore the normal one since it might have been 1599 // corrupted. 1600 Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file " 1601 + userPackagesStateFile); 1602 userPackagesStateFile.delete(); 1603 } 1604 } catch (java.io.IOException e) { 1605 // We'll try for the normal settings file. 1606 } 1607 } 1608 1609 try { 1610 if (str == null) { 1611 if (!userPackagesStateFile.exists()) { 1612 mReadMessages.append("No stopped packages file found\n"); 1613 PackageManagerService.reportSettingsProblem(Log.INFO, 1614 "No stopped packages file; " 1615 + "assuming all started"); 1616 // At first boot, make sure no packages are stopped. 1617 // We usually want to have third party apps initialize 1618 // in the stopped state, but not at first boot. Also 1619 // consider all applications to be installed. 1620 for (PackageSetting pkg : mPackages.values()) { 1621 pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 1622 true /*installed*/, 1623 false /*stopped*/, 1624 false /*notLaunched*/, 1625 false /*hidden*/, 1626 false /*suspended*/, 1627 false /*instantApp*/, 1628 false /*virtualPreload*/, 1629 null /*lastDisableAppCaller*/, 1630 null /*enabledComponents*/, 1631 null /*disabledComponents*/, 1632 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 1633 0, PackageManager.INSTALL_REASON_UNKNOWN); 1634 } 1635 return; 1636 } 1637 str = new FileInputStream(userPackagesStateFile); 1638 } 1639 final XmlPullParser parser = Xml.newPullParser(); 1640 parser.setInput(str, StandardCharsets.UTF_8.name()); 1641 1642 int type; 1643 while ((type=parser.next()) != XmlPullParser.START_TAG 1644 && type != XmlPullParser.END_DOCUMENT) { 1645 ; 1646 } 1647 1648 if (type != XmlPullParser.START_TAG) { 1649 mReadMessages.append("No start tag found in package restrictions file\n"); 1650 PackageManagerService.reportSettingsProblem(Log.WARN, 1651 "No start tag found in package manager stopped packages"); 1652 return; 1653 } 1654 1655 int maxAppLinkGeneration = 0; 1656 1657 int outerDepth = parser.getDepth(); 1658 PackageSetting ps = null; 1659 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1660 && (type != XmlPullParser.END_TAG 1661 || parser.getDepth() > outerDepth)) { 1662 if (type == XmlPullParser.END_TAG 1663 || type == XmlPullParser.TEXT) { 1664 continue; 1665 } 1666 1667 String tagName = parser.getName(); 1668 if (tagName.equals(TAG_PACKAGE)) { 1669 String name = parser.getAttributeValue(null, ATTR_NAME); 1670 ps = mPackages.get(name); 1671 if (ps == null) { 1672 Slog.w(PackageManagerService.TAG, "No package known for stopped package " 1673 + name); 1674 XmlUtils.skipCurrentTag(parser); 1675 continue; 1676 } 1677 1678 final long ceDataInode = XmlUtils.readLongAttribute(parser, ATTR_CE_DATA_INODE, 1679 0); 1680 final boolean installed = XmlUtils.readBooleanAttribute(parser, ATTR_INSTALLED, 1681 true); 1682 final boolean stopped = XmlUtils.readBooleanAttribute(parser, ATTR_STOPPED, 1683 false); 1684 final boolean notLaunched = XmlUtils.readBooleanAttribute(parser, 1685 ATTR_NOT_LAUNCHED, false); 1686 1687 // For backwards compatibility with the previous name of "blocked", which 1688 // now means hidden, read the old attribute as well. 1689 final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED); 1690 boolean hidden = blockedStr == null 1691 ? false : Boolean.parseBoolean(blockedStr); 1692 final String hiddenStr = parser.getAttributeValue(null, ATTR_HIDDEN); 1693 hidden = hiddenStr == null 1694 ? hidden : Boolean.parseBoolean(hiddenStr); 1695 1696 final boolean suspended = XmlUtils.readBooleanAttribute(parser, ATTR_SUSPENDED, 1697 false); 1698 final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser, 1699 ATTR_BLOCK_UNINSTALL, false); 1700 final boolean instantApp = XmlUtils.readBooleanAttribute(parser, 1701 ATTR_INSTANT_APP, false); 1702 final boolean virtualPreload = XmlUtils.readBooleanAttribute(parser, 1703 ATTR_VIRTUAL_PRELOAD, false); 1704 final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED, 1705 COMPONENT_ENABLED_STATE_DEFAULT); 1706 final String enabledCaller = parser.getAttributeValue(null, 1707 ATTR_ENABLED_CALLER); 1708 1709 final int verifState = XmlUtils.readIntAttribute(parser, 1710 ATTR_DOMAIN_VERIFICATON_STATE, 1711 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 1712 final int linkGeneration = XmlUtils.readIntAttribute(parser, 1713 ATTR_APP_LINK_GENERATION, 0); 1714 if (linkGeneration > maxAppLinkGeneration) { 1715 maxAppLinkGeneration = linkGeneration; 1716 } 1717 final int installReason = XmlUtils.readIntAttribute(parser, 1718 ATTR_INSTALL_REASON, PackageManager.INSTALL_REASON_UNKNOWN); 1719 1720 ArraySet<String> enabledComponents = null; 1721 ArraySet<String> disabledComponents = null; 1722 1723 int packageDepth = parser.getDepth(); 1724 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1725 && (type != XmlPullParser.END_TAG 1726 || parser.getDepth() > packageDepth)) { 1727 if (type == XmlPullParser.END_TAG 1728 || type == XmlPullParser.TEXT) { 1729 continue; 1730 } 1731 tagName = parser.getName(); 1732 if (tagName.equals(TAG_ENABLED_COMPONENTS)) { 1733 enabledComponents = readComponentsLPr(parser); 1734 } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) { 1735 disabledComponents = readComponentsLPr(parser); 1736 } 1737 } 1738 1739 if (blockUninstall) { 1740 setBlockUninstallLPw(userId, name, true); 1741 } 1742 ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched, 1743 hidden, suspended, instantApp, virtualPreload, enabledCaller, 1744 enabledComponents, disabledComponents, verifState, linkGeneration, 1745 installReason); 1746 } else if (tagName.equals("preferred-activities")) { 1747 readPreferredActivitiesLPw(parser, userId); 1748 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) { 1749 readPersistentPreferredActivitiesLPw(parser, userId); 1750 } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) { 1751 readCrossProfileIntentFiltersLPw(parser, userId); 1752 } else if (tagName.equals(TAG_DEFAULT_APPS)) { 1753 readDefaultAppsLPw(parser, userId); 1754 } else if (tagName.equals(TAG_BLOCK_UNINSTALL_PACKAGES)) { 1755 readBlockUninstallPackagesLPw(parser, userId); 1756 } else { 1757 Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " 1758 + parser.getName()); 1759 XmlUtils.skipCurrentTag(parser); 1760 } 1761 } 1762 1763 str.close(); 1764 1765 mNextAppLinkGeneration.put(userId, maxAppLinkGeneration + 1); 1766 1767 } catch (XmlPullParserException e) { 1768 mReadMessages.append("Error reading: " + e.toString()); 1769 PackageManagerService.reportSettingsProblem(Log.ERROR, 1770 "Error reading stopped packages: " + e); 1771 Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", 1772 e); 1773 1774 } catch (java.io.IOException e) { 1775 mReadMessages.append("Error reading: " + e.toString()); 1776 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 1777 Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", 1778 e); 1779 } 1780 } 1781 1782 void setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall) { 1783 ArraySet<String> packages = mBlockUninstallPackages.get(userId); 1784 if (blockUninstall) { 1785 if (packages == null) { 1786 packages = new ArraySet<String>(); 1787 mBlockUninstallPackages.put(userId, packages); 1788 } 1789 packages.add(packageName); 1790 } else if (packages != null) { 1791 packages.remove(packageName); 1792 if (packages.isEmpty()) { 1793 mBlockUninstallPackages.remove(userId); 1794 } 1795 } 1796 } 1797 1798 boolean getBlockUninstallLPr(int userId, String packageName) { 1799 ArraySet<String> packages = mBlockUninstallPackages.get(userId); 1800 if (packages == null) { 1801 return false; 1802 } 1803 return packages.contains(packageName); 1804 } 1805 1806 private ArraySet<String> readComponentsLPr(XmlPullParser parser) 1807 throws IOException, XmlPullParserException { 1808 ArraySet<String> components = null; 1809 int type; 1810 int outerDepth = parser.getDepth(); 1811 String tagName; 1812 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1813 && (type != XmlPullParser.END_TAG 1814 || parser.getDepth() > outerDepth)) { 1815 if (type == XmlPullParser.END_TAG 1816 || type == XmlPullParser.TEXT) { 1817 continue; 1818 } 1819 tagName = parser.getName(); 1820 if (tagName.equals(TAG_ITEM)) { 1821 String componentName = parser.getAttributeValue(null, ATTR_NAME); 1822 if (componentName != null) { 1823 if (components == null) { 1824 components = new ArraySet<String>(); 1825 } 1826 components.add(componentName); 1827 } 1828 } 1829 } 1830 return components; 1831 } 1832 1833 /** 1834 * Record the state of preferred activity configuration into XML. This is used both 1835 * for recording packages.xml internally and for supporting backup/restore of the 1836 * preferred activity configuration. 1837 */ 1838 void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full) 1839 throws IllegalArgumentException, IllegalStateException, IOException { 1840 serializer.startTag(null, "preferred-activities"); 1841 PreferredIntentResolver pir = mPreferredActivities.get(userId); 1842 if (pir != null) { 1843 for (final PreferredActivity pa : pir.filterSet()) { 1844 serializer.startTag(null, TAG_ITEM); 1845 pa.writeToXml(serializer, full); 1846 serializer.endTag(null, TAG_ITEM); 1847 } 1848 } 1849 serializer.endTag(null, "preferred-activities"); 1850 } 1851 1852 void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId) 1853 throws IllegalArgumentException, IllegalStateException, IOException { 1854 serializer.startTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES); 1855 PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId); 1856 if (ppir != null) { 1857 for (final PersistentPreferredActivity ppa : ppir.filterSet()) { 1858 serializer.startTag(null, TAG_ITEM); 1859 ppa.writeToXml(serializer); 1860 serializer.endTag(null, TAG_ITEM); 1861 } 1862 } 1863 serializer.endTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES); 1864 } 1865 1866 void writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId) 1867 throws IllegalArgumentException, IllegalStateException, IOException { 1868 serializer.startTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS); 1869 CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId); 1870 if (cpir != null) { 1871 for (final CrossProfileIntentFilter cpif : cpir.filterSet()) { 1872 serializer.startTag(null, TAG_ITEM); 1873 cpif.writeToXml(serializer); 1874 serializer.endTag(null, TAG_ITEM); 1875 } 1876 } 1877 serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS); 1878 } 1879 1880 void writeDomainVerificationsLPr(XmlSerializer serializer, 1881 IntentFilterVerificationInfo verificationInfo) 1882 throws IllegalArgumentException, IllegalStateException, IOException { 1883 if (verificationInfo != null && verificationInfo.getPackageName() != null) { 1884 serializer.startTag(null, TAG_DOMAIN_VERIFICATION); 1885 verificationInfo.writeToXml(serializer); 1886 if (DEBUG_DOMAIN_VERIFICATION) { 1887 Slog.d(TAG, "Wrote domain verification for package: " 1888 + verificationInfo.getPackageName()); 1889 } 1890 serializer.endTag(null, TAG_DOMAIN_VERIFICATION); 1891 } 1892 } 1893 1894 // Specifically for backup/restore 1895 void writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId) 1896 throws IllegalArgumentException, IllegalStateException, IOException { 1897 serializer.startTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION); 1898 final int N = mPackages.size(); 1899 for (int i = 0; i < N; i++) { 1900 PackageSetting ps = mPackages.valueAt(i); 1901 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 1902 if (ivi != null) { 1903 writeDomainVerificationsLPr(serializer, ivi); 1904 } 1905 } 1906 serializer.endTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION); 1907 } 1908 1909 // Specifically for backup/restore 1910 void readAllDomainVerificationsLPr(XmlPullParser parser, int userId) 1911 throws XmlPullParserException, IOException { 1912 mRestoredIntentFilterVerifications.clear(); 1913 1914 int outerDepth = parser.getDepth(); 1915 int type; 1916 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1917 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1918 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1919 continue; 1920 } 1921 1922 String tagName = parser.getName(); 1923 if (tagName.equals(TAG_DOMAIN_VERIFICATION)) { 1924 IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser); 1925 final String pkgName = ivi.getPackageName(); 1926 final PackageSetting ps = mPackages.get(pkgName); 1927 if (ps != null) { 1928 // known/existing package; update in place 1929 ps.setIntentFilterVerificationInfo(ivi); 1930 if (DEBUG_DOMAIN_VERIFICATION) { 1931 Slog.d(TAG, "Restored IVI for existing app " + pkgName 1932 + " status=" + ivi.getStatusString()); 1933 } 1934 } else { 1935 mRestoredIntentFilterVerifications.put(pkgName, ivi); 1936 if (DEBUG_DOMAIN_VERIFICATION) { 1937 Slog.d(TAG, "Restored IVI for pending app " + pkgName 1938 + " status=" + ivi.getStatusString()); 1939 } 1940 } 1941 } else { 1942 PackageManagerService.reportSettingsProblem(Log.WARN, 1943 "Unknown element under <all-intent-filter-verification>: " 1944 + parser.getName()); 1945 XmlUtils.skipCurrentTag(parser); 1946 } 1947 } 1948 } 1949 1950 // Specifically for backup/restore 1951 public void processRestoredPermissionGrantLPr(String pkgName, String permission, 1952 boolean isGranted, int restoredFlagSet, int userId) { 1953 mRuntimePermissionsPersistence.rememberRestoredUserGrantLPr( 1954 pkgName, permission, isGranted, restoredFlagSet, userId); 1955 } 1956 1957 void writeDefaultAppsLPr(XmlSerializer serializer, int userId) 1958 throws IllegalArgumentException, IllegalStateException, IOException { 1959 serializer.startTag(null, TAG_DEFAULT_APPS); 1960 String defaultBrowser = mDefaultBrowserApp.get(userId); 1961 if (!TextUtils.isEmpty(defaultBrowser)) { 1962 serializer.startTag(null, TAG_DEFAULT_BROWSER); 1963 serializer.attribute(null, ATTR_PACKAGE_NAME, defaultBrowser); 1964 serializer.endTag(null, TAG_DEFAULT_BROWSER); 1965 } 1966 String defaultDialer = mDefaultDialerApp.get(userId); 1967 if (!TextUtils.isEmpty(defaultDialer)) { 1968 serializer.startTag(null, TAG_DEFAULT_DIALER); 1969 serializer.attribute(null, ATTR_PACKAGE_NAME, defaultDialer); 1970 serializer.endTag(null, TAG_DEFAULT_DIALER); 1971 } 1972 serializer.endTag(null, TAG_DEFAULT_APPS); 1973 } 1974 1975 void writeBlockUninstallPackagesLPr(XmlSerializer serializer, int userId) 1976 throws IOException { 1977 ArraySet<String> packages = mBlockUninstallPackages.get(userId); 1978 if (packages != null) { 1979 serializer.startTag(null, TAG_BLOCK_UNINSTALL_PACKAGES); 1980 for (int i = 0; i < packages.size(); i++) { 1981 serializer.startTag(null, TAG_BLOCK_UNINSTALL); 1982 serializer.attribute(null, ATTR_PACKAGE_NAME, packages.valueAt(i)); 1983 serializer.endTag(null, TAG_BLOCK_UNINSTALL); 1984 } 1985 serializer.endTag(null, TAG_BLOCK_UNINSTALL_PACKAGES); 1986 } 1987 } 1988 1989 void writePackageRestrictionsLPr(int userId) { 1990 if (DEBUG_MU) { 1991 Log.i(TAG, "Writing package restrictions for user=" + userId); 1992 } 1993 // Keep the old stopped packages around until we know the new ones have 1994 // been successfully written. 1995 File userPackagesStateFile = getUserPackagesStateFile(userId); 1996 File backupFile = getUserPackagesStateBackupFile(userId); 1997 new File(userPackagesStateFile.getParent()).mkdirs(); 1998 if (userPackagesStateFile.exists()) { 1999 // Presence of backup settings file indicates that we failed 2000 // to persist packages earlier. So preserve the older 2001 // backup for future reference since the current packages 2002 // might have been corrupted. 2003 if (!backupFile.exists()) { 2004 if (!userPackagesStateFile.renameTo(backupFile)) { 2005 Slog.wtf(PackageManagerService.TAG, 2006 "Unable to backup user packages state file, " 2007 + "current changes will be lost at reboot"); 2008 return; 2009 } 2010 } else { 2011 userPackagesStateFile.delete(); 2012 Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup"); 2013 } 2014 } 2015 2016 try { 2017 final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile); 2018 final BufferedOutputStream str = new BufferedOutputStream(fstr); 2019 2020 final XmlSerializer serializer = new FastXmlSerializer(); 2021 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 2022 serializer.startDocument(null, true); 2023 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2024 2025 serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS); 2026 2027 for (final PackageSetting pkg : mPackages.values()) { 2028 final PackageUserState ustate = pkg.readUserState(userId); 2029 if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled); 2030 2031 serializer.startTag(null, TAG_PACKAGE); 2032 serializer.attribute(null, ATTR_NAME, pkg.name); 2033 if (ustate.ceDataInode != 0) { 2034 XmlUtils.writeLongAttribute(serializer, ATTR_CE_DATA_INODE, ustate.ceDataInode); 2035 } 2036 if (!ustate.installed) { 2037 serializer.attribute(null, ATTR_INSTALLED, "false"); 2038 } 2039 if (ustate.stopped) { 2040 serializer.attribute(null, ATTR_STOPPED, "true"); 2041 } 2042 if (ustate.notLaunched) { 2043 serializer.attribute(null, ATTR_NOT_LAUNCHED, "true"); 2044 } 2045 if (ustate.hidden) { 2046 serializer.attribute(null, ATTR_HIDDEN, "true"); 2047 } 2048 if (ustate.suspended) { 2049 serializer.attribute(null, ATTR_SUSPENDED, "true"); 2050 } 2051 if (ustate.instantApp) { 2052 serializer.attribute(null, ATTR_INSTANT_APP, "true"); 2053 } 2054 if (ustate.virtualPreload) { 2055 serializer.attribute(null, ATTR_VIRTUAL_PRELOAD, "true"); 2056 } 2057 if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) { 2058 serializer.attribute(null, ATTR_ENABLED, 2059 Integer.toString(ustate.enabled)); 2060 if (ustate.lastDisableAppCaller != null) { 2061 serializer.attribute(null, ATTR_ENABLED_CALLER, 2062 ustate.lastDisableAppCaller); 2063 } 2064 } 2065 if (ustate.domainVerificationStatus != 2066 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 2067 XmlUtils.writeIntAttribute(serializer, ATTR_DOMAIN_VERIFICATON_STATE, 2068 ustate.domainVerificationStatus); 2069 } 2070 if (ustate.appLinkGeneration != 0) { 2071 XmlUtils.writeIntAttribute(serializer, ATTR_APP_LINK_GENERATION, 2072 ustate.appLinkGeneration); 2073 } 2074 if (ustate.installReason != PackageManager.INSTALL_REASON_UNKNOWN) { 2075 serializer.attribute(null, ATTR_INSTALL_REASON, 2076 Integer.toString(ustate.installReason)); 2077 } 2078 if (!ArrayUtils.isEmpty(ustate.enabledComponents)) { 2079 serializer.startTag(null, TAG_ENABLED_COMPONENTS); 2080 for (final String name : ustate.enabledComponents) { 2081 serializer.startTag(null, TAG_ITEM); 2082 serializer.attribute(null, ATTR_NAME, name); 2083 serializer.endTag(null, TAG_ITEM); 2084 } 2085 serializer.endTag(null, TAG_ENABLED_COMPONENTS); 2086 } 2087 if (!ArrayUtils.isEmpty(ustate.disabledComponents)) { 2088 serializer.startTag(null, TAG_DISABLED_COMPONENTS); 2089 for (final String name : ustate.disabledComponents) { 2090 serializer.startTag(null, TAG_ITEM); 2091 serializer.attribute(null, ATTR_NAME, name); 2092 serializer.endTag(null, TAG_ITEM); 2093 } 2094 serializer.endTag(null, TAG_DISABLED_COMPONENTS); 2095 } 2096 2097 serializer.endTag(null, TAG_PACKAGE); 2098 } 2099 2100 writePreferredActivitiesLPr(serializer, userId, true); 2101 writePersistentPreferredActivitiesLPr(serializer, userId); 2102 writeCrossProfileIntentFiltersLPr(serializer, userId); 2103 writeDefaultAppsLPr(serializer, userId); 2104 writeBlockUninstallPackagesLPr(serializer, userId); 2105 2106 serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); 2107 2108 serializer.endDocument(); 2109 2110 str.flush(); 2111 FileUtils.sync(fstr); 2112 str.close(); 2113 2114 // New settings successfully written, old ones are no longer 2115 // needed. 2116 backupFile.delete(); 2117 FileUtils.setPermissions(userPackagesStateFile.toString(), 2118 FileUtils.S_IRUSR|FileUtils.S_IWUSR 2119 |FileUtils.S_IRGRP|FileUtils.S_IWGRP, 2120 -1, -1); 2121 2122 // Done, all is good! 2123 return; 2124 } catch(java.io.IOException e) { 2125 Slog.wtf(PackageManagerService.TAG, 2126 "Unable to write package manager user packages state, " 2127 + " current changes will be lost at reboot", e); 2128 } 2129 2130 // Clean up partially written files 2131 if (userPackagesStateFile.exists()) { 2132 if (!userPackagesStateFile.delete()) { 2133 Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: " 2134 + mStoppedPackagesFilename); 2135 } 2136 } 2137 } 2138 2139 void readInstallPermissionsLPr(XmlPullParser parser, 2140 PermissionsState permissionsState) throws IOException, XmlPullParserException { 2141 int outerDepth = parser.getDepth(); 2142 int type; 2143 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 2144 && (type != XmlPullParser.END_TAG 2145 || parser.getDepth() > outerDepth)) { 2146 if (type == XmlPullParser.END_TAG 2147 || type == XmlPullParser.TEXT) { 2148 continue; 2149 } 2150 String tagName = parser.getName(); 2151 if (tagName.equals(TAG_ITEM)) { 2152 String name = parser.getAttributeValue(null, ATTR_NAME); 2153 2154 BasePermission bp = mPermissions.getPermission(name); 2155 if (bp == null) { 2156 Slog.w(PackageManagerService.TAG, "Unknown permission: " + name); 2157 XmlUtils.skipCurrentTag(parser); 2158 continue; 2159 } 2160 2161 String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED); 2162 final boolean granted = grantedStr == null 2163 || Boolean.parseBoolean(grantedStr); 2164 2165 String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS); 2166 final int flags = (flagsStr != null) 2167 ? Integer.parseInt(flagsStr, 16) : 0; 2168 2169 if (granted) { 2170 if (permissionsState.grantInstallPermission(bp) == 2171 PermissionsState.PERMISSION_OPERATION_FAILURE) { 2172 Slog.w(PackageManagerService.TAG, "Permission already added: " + name); 2173 XmlUtils.skipCurrentTag(parser); 2174 } else { 2175 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 2176 PackageManager.MASK_PERMISSION_FLAGS, flags); 2177 } 2178 } else { 2179 if (permissionsState.revokeInstallPermission(bp) == 2180 PermissionsState.PERMISSION_OPERATION_FAILURE) { 2181 Slog.w(PackageManagerService.TAG, "Permission already added: " + name); 2182 XmlUtils.skipCurrentTag(parser); 2183 } else { 2184 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 2185 PackageManager.MASK_PERMISSION_FLAGS, flags); 2186 } 2187 } 2188 } else { 2189 Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: " 2190 + parser.getName()); 2191 XmlUtils.skipCurrentTag(parser); 2192 } 2193 } 2194 } 2195 2196 void writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates) 2197 throws IOException { 2198 if (permissionStates.isEmpty()) { 2199 return; 2200 } 2201 2202 serializer.startTag(null, TAG_PERMISSIONS); 2203 2204 for (PermissionState permissionState : permissionStates) { 2205 serializer.startTag(null, TAG_ITEM); 2206 serializer.attribute(null, ATTR_NAME, permissionState.getName()); 2207 serializer.attribute(null, ATTR_GRANTED, String.valueOf(permissionState.isGranted())); 2208 serializer.attribute(null, ATTR_FLAGS, Integer.toHexString(permissionState.getFlags())); 2209 serializer.endTag(null, TAG_ITEM); 2210 } 2211 2212 serializer.endTag(null, TAG_PERMISSIONS); 2213 } 2214 2215 void writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames) 2216 throws IOException { 2217 if (childPackageNames == null) { 2218 return; 2219 } 2220 final int childCount = childPackageNames.size(); 2221 for (int i = 0; i < childCount; i++) { 2222 String childPackageName = childPackageNames.get(i); 2223 serializer.startTag(null, TAG_CHILD_PACKAGE); 2224 serializer.attribute(null, ATTR_NAME, childPackageName); 2225 serializer.endTag(null, TAG_CHILD_PACKAGE); 2226 } 2227 } 2228 2229 void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs) 2230 throws IOException, XmlPullParserException { 2231 int outerDepth = parser.getDepth(); 2232 int type; 2233 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2234 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2235 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2236 continue; 2237 } 2238 String libName = parser.getAttributeValue(null, ATTR_NAME); 2239 String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION); 2240 2241 long libVersion = -1; 2242 try { 2243 libVersion = Long.parseLong(libVersionStr); 2244 } catch (NumberFormatException e) { 2245 // ignore 2246 } 2247 2248 if (libName != null && libVersion >= 0) { 2249 outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class, 2250 outPs.usesStaticLibraries, libName); 2251 outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong( 2252 outPs.usesStaticLibrariesVersions, libVersion); 2253 } 2254 2255 XmlUtils.skipCurrentTag(parser); 2256 } 2257 } 2258 2259 void writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries, 2260 long[] usesStaticLibraryVersions) throws IOException { 2261 if (ArrayUtils.isEmpty(usesStaticLibraries) || ArrayUtils.isEmpty(usesStaticLibraryVersions) 2262 || usesStaticLibraries.length != usesStaticLibraryVersions.length) { 2263 return; 2264 } 2265 final int libCount = usesStaticLibraries.length; 2266 for (int i = 0; i < libCount; i++) { 2267 final String libName = usesStaticLibraries[i]; 2268 final long libVersion = usesStaticLibraryVersions[i]; 2269 serializer.startTag(null, TAG_USES_STATIC_LIB); 2270 serializer.attribute(null, ATTR_NAME, libName); 2271 serializer.attribute(null, ATTR_VERSION, Long.toString(libVersion)); 2272 serializer.endTag(null, TAG_USES_STATIC_LIB); 2273 } 2274 } 2275 2276 // Note: assumed "stopped" field is already cleared in all packages. 2277 // Legacy reader, used to read in the old file format after an upgrade. Not used after that. 2278 void readStoppedLPw() { 2279 FileInputStream str = null; 2280 if (mBackupStoppedPackagesFilename.exists()) { 2281 try { 2282 str = new FileInputStream(mBackupStoppedPackagesFilename); 2283 mReadMessages.append("Reading from backup stopped packages file\n"); 2284 PackageManagerService.reportSettingsProblem(Log.INFO, 2285 "Need to read from backup stopped packages file"); 2286 if (mSettingsFilename.exists()) { 2287 // If both the backup and normal file exist, we 2288 // ignore the normal one since it might have been 2289 // corrupted. 2290 Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file " 2291 + mStoppedPackagesFilename); 2292 mStoppedPackagesFilename.delete(); 2293 } 2294 } catch (java.io.IOException e) { 2295 // We'll try for the normal settings file. 2296 } 2297 } 2298 2299 try { 2300 if (str == null) { 2301 if (!mStoppedPackagesFilename.exists()) { 2302 mReadMessages.append("No stopped packages file found\n"); 2303 PackageManagerService.reportSettingsProblem(Log.INFO, 2304 "No stopped packages file file; assuming all started"); 2305 // At first boot, make sure no packages are stopped. 2306 // We usually want to have third party apps initialize 2307 // in the stopped state, but not at first boot. 2308 for (PackageSetting pkg : mPackages.values()) { 2309 pkg.setStopped(false, 0); 2310 pkg.setNotLaunched(false, 0); 2311 } 2312 return; 2313 } 2314 str = new FileInputStream(mStoppedPackagesFilename); 2315 } 2316 final XmlPullParser parser = Xml.newPullParser(); 2317 parser.setInput(str, null); 2318 2319 int type; 2320 while ((type=parser.next()) != XmlPullParser.START_TAG 2321 && type != XmlPullParser.END_DOCUMENT) { 2322 ; 2323 } 2324 2325 if (type != XmlPullParser.START_TAG) { 2326 mReadMessages.append("No start tag found in stopped packages file\n"); 2327 PackageManagerService.reportSettingsProblem(Log.WARN, 2328 "No start tag found in package manager stopped packages"); 2329 return; 2330 } 2331 2332 int outerDepth = parser.getDepth(); 2333 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 2334 && (type != XmlPullParser.END_TAG 2335 || parser.getDepth() > outerDepth)) { 2336 if (type == XmlPullParser.END_TAG 2337 || type == XmlPullParser.TEXT) { 2338 continue; 2339 } 2340 2341 String tagName = parser.getName(); 2342 if (tagName.equals(TAG_PACKAGE)) { 2343 String name = parser.getAttributeValue(null, ATTR_NAME); 2344 PackageSetting ps = mPackages.get(name); 2345 if (ps != null) { 2346 ps.setStopped(true, 0); 2347 if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) { 2348 ps.setNotLaunched(true, 0); 2349 } 2350 } else { 2351 Slog.w(PackageManagerService.TAG, 2352 "No package known for stopped package " + name); 2353 } 2354 XmlUtils.skipCurrentTag(parser); 2355 } else { 2356 Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " 2357 + parser.getName()); 2358 XmlUtils.skipCurrentTag(parser); 2359 } 2360 } 2361 2362 str.close(); 2363 2364 } catch (XmlPullParserException e) { 2365 mReadMessages.append("Error reading: " + e.toString()); 2366 PackageManagerService.reportSettingsProblem(Log.ERROR, 2367 "Error reading stopped packages: " + e); 2368 Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", 2369 e); 2370 2371 } catch (java.io.IOException e) { 2372 mReadMessages.append("Error reading: " + e.toString()); 2373 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 2374 Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", 2375 e); 2376 2377 } 2378 } 2379 2380 void writeLPr() { 2381 //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024); 2382 2383 // Keep the old settings around until we know the new ones have 2384 // been successfully written. 2385 if (mSettingsFilename.exists()) { 2386 // Presence of backup settings file indicates that we failed 2387 // to persist settings earlier. So preserve the older 2388 // backup for future reference since the current settings 2389 // might have been corrupted. 2390 if (!mBackupSettingsFilename.exists()) { 2391 if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) { 2392 Slog.wtf(PackageManagerService.TAG, 2393 "Unable to backup package manager settings, " 2394 + " current changes will be lost at reboot"); 2395 return; 2396 } 2397 } else { 2398 mSettingsFilename.delete(); 2399 Slog.w(PackageManagerService.TAG, "Preserving older settings backup"); 2400 } 2401 } 2402 2403 mPastSignatures.clear(); 2404 2405 try { 2406 FileOutputStream fstr = new FileOutputStream(mSettingsFilename); 2407 BufferedOutputStream str = new BufferedOutputStream(fstr); 2408 2409 //XmlSerializer serializer = XmlUtils.serializerInstance(); 2410 XmlSerializer serializer = new FastXmlSerializer(); 2411 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 2412 serializer.startDocument(null, true); 2413 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2414 2415 serializer.startTag(null, "packages"); 2416 2417 for (int i = 0; i < mVersion.size(); i++) { 2418 final String volumeUuid = mVersion.keyAt(i); 2419 final VersionInfo ver = mVersion.valueAt(i); 2420 2421 serializer.startTag(null, TAG_VERSION); 2422 XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid); 2423 XmlUtils.writeIntAttribute(serializer, ATTR_SDK_VERSION, ver.sdkVersion); 2424 XmlUtils.writeIntAttribute(serializer, ATTR_DATABASE_VERSION, ver.databaseVersion); 2425 XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint); 2426 serializer.endTag(null, TAG_VERSION); 2427 } 2428 2429 if (mVerifierDeviceIdentity != null) { 2430 serializer.startTag(null, "verifier"); 2431 serializer.attribute(null, "device", mVerifierDeviceIdentity.toString()); 2432 serializer.endTag(null, "verifier"); 2433 } 2434 2435 if (mReadExternalStorageEnforced != null) { 2436 serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE); 2437 serializer.attribute( 2438 null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0"); 2439 serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE); 2440 } 2441 2442 serializer.startTag(null, "permission-trees"); 2443 mPermissions.writePermissionTrees(serializer); 2444 serializer.endTag(null, "permission-trees"); 2445 2446 serializer.startTag(null, "permissions"); 2447 mPermissions.writePermissions(serializer); 2448 serializer.endTag(null, "permissions"); 2449 2450 for (final PackageSetting pkg : mPackages.values()) { 2451 writePackageLPr(serializer, pkg); 2452 } 2453 2454 for (final PackageSetting pkg : mDisabledSysPackages.values()) { 2455 writeDisabledSysPackageLPr(serializer, pkg); 2456 } 2457 2458 for (final SharedUserSetting usr : mSharedUsers.values()) { 2459 serializer.startTag(null, "shared-user"); 2460 serializer.attribute(null, ATTR_NAME, usr.name); 2461 serializer.attribute(null, "userId", 2462 Integer.toString(usr.userId)); 2463 usr.signatures.writeXml(serializer, "sigs", mPastSignatures); 2464 writePermissionsLPr(serializer, usr.getPermissionsState() 2465 .getInstallPermissionStates()); 2466 serializer.endTag(null, "shared-user"); 2467 } 2468 2469 if (mPackagesToBeCleaned.size() > 0) { 2470 for (PackageCleanItem item : mPackagesToBeCleaned) { 2471 final String userStr = Integer.toString(item.userId); 2472 serializer.startTag(null, "cleaning-package"); 2473 serializer.attribute(null, ATTR_NAME, item.packageName); 2474 serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false"); 2475 serializer.attribute(null, ATTR_USER, userStr); 2476 serializer.endTag(null, "cleaning-package"); 2477 } 2478 } 2479 2480 if (mRenamedPackages.size() > 0) { 2481 for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) { 2482 serializer.startTag(null, "renamed-package"); 2483 serializer.attribute(null, "new", e.getKey()); 2484 serializer.attribute(null, "old", e.getValue()); 2485 serializer.endTag(null, "renamed-package"); 2486 } 2487 } 2488 2489 final int numIVIs = mRestoredIntentFilterVerifications.size(); 2490 if (numIVIs > 0) { 2491 if (DEBUG_DOMAIN_VERIFICATION) { 2492 Slog.i(TAG, "Writing restored-ivi entries to packages.xml"); 2493 } 2494 serializer.startTag(null, "restored-ivi"); 2495 for (int i = 0; i < numIVIs; i++) { 2496 IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i); 2497 writeDomainVerificationsLPr(serializer, ivi); 2498 } 2499 serializer.endTag(null, "restored-ivi"); 2500 } else { 2501 if (DEBUG_DOMAIN_VERIFICATION) { 2502 Slog.i(TAG, " no restored IVI entries to write"); 2503 } 2504 } 2505 2506 mKeySetManagerService.writeKeySetManagerServiceLPr(serializer); 2507 2508 serializer.endTag(null, "packages"); 2509 2510 serializer.endDocument(); 2511 2512 str.flush(); 2513 FileUtils.sync(fstr); 2514 str.close(); 2515 2516 // New settings successfully written, old ones are no longer 2517 // needed. 2518 mBackupSettingsFilename.delete(); 2519 FileUtils.setPermissions(mSettingsFilename.toString(), 2520 FileUtils.S_IRUSR|FileUtils.S_IWUSR 2521 |FileUtils.S_IRGRP|FileUtils.S_IWGRP, 2522 -1, -1); 2523 2524 writeKernelMappingLPr(); 2525 writePackageListLPr(); 2526 writeAllUsersPackageRestrictionsLPr(); 2527 writeAllRuntimePermissionsLPr(); 2528 return; 2529 2530 } catch(java.io.IOException e) { 2531 Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " 2532 + "current changes will be lost at reboot", e); 2533 } 2534 // Clean up partially written files 2535 if (mSettingsFilename.exists()) { 2536 if (!mSettingsFilename.delete()) { 2537 Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " 2538 + mSettingsFilename); 2539 } 2540 } 2541 //Debug.stopMethodTracing(); 2542 } 2543 2544 private void writeKernelRemoveUserLPr(int userId) { 2545 if (mKernelMappingFilename == null) return; 2546 2547 File removeUserIdFile = new File(mKernelMappingFilename, "remove_userid"); 2548 if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + userId + " to " + removeUserIdFile 2549 .getAbsolutePath()); 2550 writeIntToFile(removeUserIdFile, userId); 2551 } 2552 2553 void writeKernelMappingLPr() { 2554 if (mKernelMappingFilename == null) return; 2555 2556 final String[] known = mKernelMappingFilename.list(); 2557 final ArraySet<String> knownSet = new ArraySet<>(known.length); 2558 for (String name : known) { 2559 knownSet.add(name); 2560 } 2561 2562 for (final PackageSetting ps : mPackages.values()) { 2563 // Package is actively claimed 2564 knownSet.remove(ps.name); 2565 writeKernelMappingLPr(ps); 2566 } 2567 2568 // Remove any unclaimed mappings 2569 for (int i = 0; i < knownSet.size(); i++) { 2570 final String name = knownSet.valueAt(i); 2571 if (DEBUG_KERNEL) Slog.d(TAG, "Dropping mapping " + name); 2572 2573 mKernelMapping.remove(name); 2574 new File(mKernelMappingFilename, name).delete(); 2575 } 2576 } 2577 2578 void writeKernelMappingLPr(PackageSetting ps) { 2579 if (mKernelMappingFilename == null || ps == null || ps.name == null) return; 2580 2581 KernelPackageState cur = mKernelMapping.get(ps.name); 2582 final boolean firstTime = cur == null; 2583 int[] excludedUserIds = ps.getNotInstalledUserIds(); 2584 final boolean userIdsChanged = firstTime 2585 || !Arrays.equals(excludedUserIds, cur.excludedUserIds); 2586 2587 // Package directory 2588 final File dir = new File(mKernelMappingFilename, ps.name); 2589 2590 if (firstTime) { 2591 dir.mkdir(); 2592 // Create a new mapping state 2593 cur = new KernelPackageState(); 2594 mKernelMapping.put(ps.name, cur); 2595 } 2596 2597 // If mapping is incorrect or non-existent, write the appid file 2598 if (cur.appId != ps.appId) { 2599 final File appIdFile = new File(dir, "appid"); 2600 writeIntToFile(appIdFile, ps.appId); 2601 if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + ps.name + " to " + ps.appId); 2602 } 2603 2604 if (userIdsChanged) { 2605 // Build the exclusion list -- the ids to add to the exclusion list 2606 for (int i = 0; i < excludedUserIds.length; i++) { 2607 if (cur.excludedUserIds == null || !ArrayUtils.contains(cur.excludedUserIds, 2608 excludedUserIds[i])) { 2609 writeIntToFile(new File(dir, "excluded_userids"), excludedUserIds[i]); 2610 if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + excludedUserIds[i] + " to " 2611 + ps.name + "/excluded_userids"); 2612 } 2613 } 2614 // Build the inclusion list -- the ids to remove from the exclusion list 2615 if (cur.excludedUserIds != null) { 2616 for (int i = 0; i < cur.excludedUserIds.length; i++) { 2617 if (!ArrayUtils.contains(excludedUserIds, cur.excludedUserIds[i])) { 2618 writeIntToFile(new File(dir, "clear_userid"), 2619 cur.excludedUserIds[i]); 2620 if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + cur.excludedUserIds[i] + " to " 2621 + ps.name + "/clear_userid"); 2622 2623 } 2624 } 2625 } 2626 cur.excludedUserIds = excludedUserIds; 2627 } 2628 } 2629 2630 private void writeIntToFile(File file, int value) { 2631 try { 2632 FileUtils.bytesToFile(file.getAbsolutePath(), 2633 Integer.toString(value).getBytes(StandardCharsets.US_ASCII)); 2634 } catch (IOException ignored) { 2635 Slog.w(TAG, "Couldn't write " + value + " to " + file.getAbsolutePath()); 2636 } 2637 } 2638 2639 void writePackageListLPr() { 2640 writePackageListLPr(-1); 2641 } 2642 2643 void writePackageListLPr(int creatingUserId) { 2644 // Only derive GIDs for active users (not dying) 2645 final List<UserInfo> users = UserManagerService.getInstance().getUsers(true); 2646 int[] userIds = new int[users.size()]; 2647 for (int i = 0; i < userIds.length; i++) { 2648 userIds[i] = users.get(i).id; 2649 } 2650 if (creatingUserId != -1) { 2651 userIds = ArrayUtils.appendInt(userIds, creatingUserId); 2652 } 2653 2654 // Write package list file now, use a JournaledFile. 2655 File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp"); 2656 JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile); 2657 2658 final File writeTarget = journal.chooseForWrite(); 2659 FileOutputStream fstr; 2660 BufferedWriter writer = null; 2661 try { 2662 fstr = new FileOutputStream(writeTarget); 2663 writer = new BufferedWriter(new OutputStreamWriter(fstr, Charset.defaultCharset())); 2664 FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 2665 2666 StringBuilder sb = new StringBuilder(); 2667 for (final PackageSetting pkg : mPackages.values()) { 2668 if (pkg.pkg == null || pkg.pkg.applicationInfo == null 2669 || pkg.pkg.applicationInfo.dataDir == null) { 2670 if (!"android".equals(pkg.name)) { 2671 Slog.w(TAG, "Skipping " + pkg + " due to missing metadata"); 2672 } 2673 continue; 2674 } 2675 2676 final ApplicationInfo ai = pkg.pkg.applicationInfo; 2677 final String dataPath = ai.dataDir; 2678 final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 2679 final int[] gids = pkg.getPermissionsState().computeGids(userIds); 2680 2681 // Avoid any application that has a space in its path. 2682 if (dataPath.indexOf(' ') >= 0) 2683 continue; 2684 2685 // we store on each line the following information for now: 2686 // 2687 // pkgName - package name 2688 // userId - application-specific user id 2689 // debugFlag - 0 or 1 if the package is debuggable. 2690 // dataPath - path to package's data path 2691 // seinfo - seinfo label for the app (assigned at install time) 2692 // gids - supplementary gids this app launches with 2693 // 2694 // NOTE: We prefer not to expose all ApplicationInfo flags for now. 2695 // 2696 // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS 2697 // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES: 2698 // frameworks/base/libs/packagelistparser 2699 // system/core/run-as/run-as.c 2700 // 2701 sb.setLength(0); 2702 sb.append(ai.packageName); 2703 sb.append(" "); 2704 sb.append(ai.uid); 2705 sb.append(isDebug ? " 1 " : " 0 "); 2706 sb.append(dataPath); 2707 sb.append(" "); 2708 sb.append(ai.seInfo); 2709 sb.append(" "); 2710 if (gids != null && gids.length > 0) { 2711 sb.append(gids[0]); 2712 for (int i = 1; i < gids.length; i++) { 2713 sb.append(","); 2714 sb.append(gids[i]); 2715 } 2716 } else { 2717 sb.append("none"); 2718 } 2719 sb.append("\n"); 2720 writer.append(sb); 2721 } 2722 writer.flush(); 2723 FileUtils.sync(fstr); 2724 writer.close(); 2725 journal.commit(); 2726 } catch (Exception e) { 2727 Slog.wtf(TAG, "Failed to write packages.list", e); 2728 IoUtils.closeQuietly(writer); 2729 journal.rollback(); 2730 } 2731 } 2732 2733 void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg) 2734 throws java.io.IOException { 2735 serializer.startTag(null, "updated-package"); 2736 serializer.attribute(null, ATTR_NAME, pkg.name); 2737 if (pkg.realName != null) { 2738 serializer.attribute(null, "realName", pkg.realName); 2739 } 2740 serializer.attribute(null, "codePath", pkg.codePathString); 2741 serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); 2742 serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime)); 2743 serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); 2744 serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); 2745 if (!pkg.resourcePathString.equals(pkg.codePathString)) { 2746 serializer.attribute(null, "resourcePath", pkg.resourcePathString); 2747 } 2748 if (pkg.legacyNativeLibraryPathString != null) { 2749 serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString); 2750 } 2751 if (pkg.primaryCpuAbiString != null) { 2752 serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString); 2753 } 2754 if (pkg.secondaryCpuAbiString != null) { 2755 serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString); 2756 } 2757 if (pkg.cpuAbiOverrideString != null) { 2758 serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString); 2759 } 2760 2761 if (pkg.sharedUser == null) { 2762 serializer.attribute(null, "userId", Integer.toString(pkg.appId)); 2763 } else { 2764 serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId)); 2765 } 2766 2767 if (pkg.parentPackageName != null) { 2768 serializer.attribute(null, "parentPackageName", pkg.parentPackageName); 2769 } 2770 2771 writeChildPackagesLPw(serializer, pkg.childPackageNames); 2772 2773 writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions); 2774 2775 // If this is a shared user, the permissions will be written there. 2776 if (pkg.sharedUser == null) { 2777 writePermissionsLPr(serializer, pkg.getPermissionsState() 2778 .getInstallPermissionStates()); 2779 } 2780 2781 serializer.endTag(null, "updated-package"); 2782 } 2783 2784 void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg) 2785 throws java.io.IOException { 2786 serializer.startTag(null, "package"); 2787 serializer.attribute(null, ATTR_NAME, pkg.name); 2788 if (pkg.realName != null) { 2789 serializer.attribute(null, "realName", pkg.realName); 2790 } 2791 serializer.attribute(null, "codePath", pkg.codePathString); 2792 if (!pkg.resourcePathString.equals(pkg.codePathString)) { 2793 serializer.attribute(null, "resourcePath", pkg.resourcePathString); 2794 } 2795 2796 if (pkg.legacyNativeLibraryPathString != null) { 2797 serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString); 2798 } 2799 if (pkg.primaryCpuAbiString != null) { 2800 serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString); 2801 } 2802 if (pkg.secondaryCpuAbiString != null) { 2803 serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString); 2804 } 2805 if (pkg.cpuAbiOverrideString != null) { 2806 serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString); 2807 } 2808 2809 serializer.attribute(null, "publicFlags", Integer.toString(pkg.pkgFlags)); 2810 serializer.attribute(null, "privateFlags", Integer.toString(pkg.pkgPrivateFlags)); 2811 serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); 2812 serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime)); 2813 serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); 2814 serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); 2815 if (pkg.sharedUser == null) { 2816 serializer.attribute(null, "userId", Integer.toString(pkg.appId)); 2817 } else { 2818 serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId)); 2819 } 2820 if (pkg.uidError) { 2821 serializer.attribute(null, "uidError", "true"); 2822 } 2823 if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) { 2824 serializer.attribute(null, "installStatus", "false"); 2825 } 2826 if (pkg.installerPackageName != null) { 2827 serializer.attribute(null, "installer", pkg.installerPackageName); 2828 } 2829 if (pkg.isOrphaned) { 2830 serializer.attribute(null, "isOrphaned", "true"); 2831 } 2832 if (pkg.volumeUuid != null) { 2833 serializer.attribute(null, "volumeUuid", pkg.volumeUuid); 2834 } 2835 if (pkg.categoryHint != ApplicationInfo.CATEGORY_UNDEFINED) { 2836 serializer.attribute(null, "categoryHint", 2837 Integer.toString(pkg.categoryHint)); 2838 } 2839 if (pkg.parentPackageName != null) { 2840 serializer.attribute(null, "parentPackageName", pkg.parentPackageName); 2841 } 2842 if (pkg.updateAvailable) { 2843 serializer.attribute(null, "updateAvailable", "true"); 2844 } 2845 2846 writeChildPackagesLPw(serializer, pkg.childPackageNames); 2847 2848 writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions); 2849 2850 pkg.signatures.writeXml(serializer, "sigs", mPastSignatures); 2851 2852 writePermissionsLPr(serializer, pkg.getPermissionsState() 2853 .getInstallPermissionStates()); 2854 2855 writeSigningKeySetLPr(serializer, pkg.keySetData); 2856 writeUpgradeKeySetsLPr(serializer, pkg.keySetData); 2857 writeKeySetAliasesLPr(serializer, pkg.keySetData); 2858 writeDomainVerificationsLPr(serializer, pkg.verificationInfo); 2859 2860 serializer.endTag(null, "package"); 2861 } 2862 2863 void writeSigningKeySetLPr(XmlSerializer serializer, 2864 PackageKeySetData data) throws IOException { 2865 serializer.startTag(null, "proper-signing-keyset"); 2866 serializer.attribute(null, "identifier", 2867 Long.toString(data.getProperSigningKeySet())); 2868 serializer.endTag(null, "proper-signing-keyset"); 2869 } 2870 2871 void writeUpgradeKeySetsLPr(XmlSerializer serializer, 2872 PackageKeySetData data) throws IOException { 2873 if (data.isUsingUpgradeKeySets()) { 2874 for (long id : data.getUpgradeKeySets()) { 2875 serializer.startTag(null, "upgrade-keyset"); 2876 serializer.attribute(null, "identifier", Long.toString(id)); 2877 serializer.endTag(null, "upgrade-keyset"); 2878 } 2879 } 2880 } 2881 2882 void writeKeySetAliasesLPr(XmlSerializer serializer, 2883 PackageKeySetData data) throws IOException { 2884 for (Map.Entry<String, Long> e: data.getAliases().entrySet()) { 2885 serializer.startTag(null, "defined-keyset"); 2886 serializer.attribute(null, "alias", e.getKey()); 2887 serializer.attribute(null, "identifier", Long.toString(e.getValue())); 2888 serializer.endTag(null, "defined-keyset"); 2889 } 2890 } 2891 2892 void writePermissionLPr(XmlSerializer serializer, BasePermission bp) throws IOException { 2893 bp.writeLPr(serializer); 2894 } 2895 2896 ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() { 2897 final ArraySet<String> kList = new ArraySet<String>(mPackages.keySet()); 2898 final Iterator<String> its = kList.iterator(); 2899 final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>(); 2900 while (its.hasNext()) { 2901 final String key = its.next(); 2902 final PackageSetting ps = mPackages.get(key); 2903 if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) { 2904 ret.add(ps); 2905 } 2906 } 2907 return ret; 2908 } 2909 2910 void addPackageToCleanLPw(PackageCleanItem pkg) { 2911 if (!mPackagesToBeCleaned.contains(pkg)) { 2912 mPackagesToBeCleaned.add(pkg); 2913 } 2914 } 2915 2916 boolean readLPw(@NonNull List<UserInfo> users) { 2917 FileInputStream str = null; 2918 if (mBackupSettingsFilename.exists()) { 2919 try { 2920 str = new FileInputStream(mBackupSettingsFilename); 2921 mReadMessages.append("Reading from backup settings file\n"); 2922 PackageManagerService.reportSettingsProblem(Log.INFO, 2923 "Need to read from backup settings file"); 2924 if (mSettingsFilename.exists()) { 2925 // If both the backup and settings file exist, we 2926 // ignore the settings since it might have been 2927 // corrupted. 2928 Slog.w(PackageManagerService.TAG, "Cleaning up settings file " 2929 + mSettingsFilename); 2930 mSettingsFilename.delete(); 2931 } 2932 } catch (java.io.IOException e) { 2933 // We'll try for the normal settings file. 2934 } 2935 } 2936 2937 mPendingPackages.clear(); 2938 mPastSignatures.clear(); 2939 mKeySetRefs.clear(); 2940 mInstallerPackages.clear(); 2941 2942 try { 2943 if (str == null) { 2944 if (!mSettingsFilename.exists()) { 2945 mReadMessages.append("No settings file found\n"); 2946 PackageManagerService.reportSettingsProblem(Log.INFO, 2947 "No settings file; creating initial state"); 2948 // It's enough to just touch version details to create them 2949 // with default values 2950 findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent(); 2951 findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent(); 2952 return false; 2953 } 2954 str = new FileInputStream(mSettingsFilename); 2955 } 2956 XmlPullParser parser = Xml.newPullParser(); 2957 parser.setInput(str, StandardCharsets.UTF_8.name()); 2958 2959 int type; 2960 while ((type = parser.next()) != XmlPullParser.START_TAG 2961 && type != XmlPullParser.END_DOCUMENT) { 2962 ; 2963 } 2964 2965 if (type != XmlPullParser.START_TAG) { 2966 mReadMessages.append("No start tag found in settings file\n"); 2967 PackageManagerService.reportSettingsProblem(Log.WARN, 2968 "No start tag found in package manager settings"); 2969 Slog.wtf(PackageManagerService.TAG, 2970 "No start tag found in package manager settings"); 2971 return false; 2972 } 2973 2974 int outerDepth = parser.getDepth(); 2975 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2976 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2977 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2978 continue; 2979 } 2980 2981 String tagName = parser.getName(); 2982 if (tagName.equals("package")) { 2983 readPackageLPw(parser); 2984 } else if (tagName.equals("permissions")) { 2985 mPermissions.readPermissions(parser); 2986 } else if (tagName.equals("permission-trees")) { 2987 mPermissions.readPermissionTrees(parser); 2988 } else if (tagName.equals("shared-user")) { 2989 readSharedUserLPw(parser); 2990 } else if (tagName.equals("preferred-packages")) { 2991 // no longer used. 2992 } else if (tagName.equals("preferred-activities")) { 2993 // Upgrading from old single-user implementation; 2994 // these are the preferred activities for user 0. 2995 readPreferredActivitiesLPw(parser, 0); 2996 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) { 2997 // TODO: check whether this is okay! as it is very 2998 // similar to how preferred-activities are treated 2999 readPersistentPreferredActivitiesLPw(parser, 0); 3000 } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) { 3001 // TODO: check whether this is okay! as it is very 3002 // similar to how preferred-activities are treated 3003 readCrossProfileIntentFiltersLPw(parser, 0); 3004 } else if (tagName.equals(TAG_DEFAULT_BROWSER)) { 3005 readDefaultAppsLPw(parser, 0); 3006 } else if (tagName.equals("updated-package")) { 3007 readDisabledSysPackageLPw(parser); 3008 } else if (tagName.equals("cleaning-package")) { 3009 String name = parser.getAttributeValue(null, ATTR_NAME); 3010 String userStr = parser.getAttributeValue(null, ATTR_USER); 3011 String codeStr = parser.getAttributeValue(null, ATTR_CODE); 3012 if (name != null) { 3013 int userId = UserHandle.USER_SYSTEM; 3014 boolean andCode = true; 3015 try { 3016 if (userStr != null) { 3017 userId = Integer.parseInt(userStr); 3018 } 3019 } catch (NumberFormatException e) { 3020 } 3021 if (codeStr != null) { 3022 andCode = Boolean.parseBoolean(codeStr); 3023 } 3024 addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode)); 3025 } 3026 } else if (tagName.equals("renamed-package")) { 3027 String nname = parser.getAttributeValue(null, "new"); 3028 String oname = parser.getAttributeValue(null, "old"); 3029 if (nname != null && oname != null) { 3030 mRenamedPackages.put(nname, oname); 3031 } 3032 } else if (tagName.equals("restored-ivi")) { 3033 readRestoredIntentFilterVerifications(parser); 3034 } else if (tagName.equals("last-platform-version")) { 3035 // Upgrade from older XML schema 3036 final VersionInfo internal = findOrCreateVersion( 3037 StorageManager.UUID_PRIVATE_INTERNAL); 3038 final VersionInfo external = findOrCreateVersion( 3039 StorageManager.UUID_PRIMARY_PHYSICAL); 3040 3041 internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0); 3042 external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0); 3043 internal.fingerprint = external.fingerprint = 3044 XmlUtils.readStringAttribute(parser, "fingerprint"); 3045 3046 } else if (tagName.equals("database-version")) { 3047 // Upgrade from older XML schema 3048 final VersionInfo internal = findOrCreateVersion( 3049 StorageManager.UUID_PRIVATE_INTERNAL); 3050 final VersionInfo external = findOrCreateVersion( 3051 StorageManager.UUID_PRIMARY_PHYSICAL); 3052 3053 internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0); 3054 external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0); 3055 3056 } else if (tagName.equals("verifier")) { 3057 final String deviceIdentity = parser.getAttributeValue(null, "device"); 3058 try { 3059 mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity); 3060 } catch (IllegalArgumentException e) { 3061 Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: " 3062 + e.getMessage()); 3063 } 3064 } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) { 3065 final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT); 3066 mReadExternalStorageEnforced = 3067 "1".equals(enforcement) ? Boolean.TRUE : Boolean.FALSE; 3068 } else if (tagName.equals("keyset-settings")) { 3069 mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs); 3070 } else if (TAG_VERSION.equals(tagName)) { 3071 final String volumeUuid = XmlUtils.readStringAttribute(parser, 3072 ATTR_VOLUME_UUID); 3073 final VersionInfo ver = findOrCreateVersion(volumeUuid); 3074 ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION); 3075 ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_DATABASE_VERSION); 3076 ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT); 3077 } else { 3078 Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: " 3079 + parser.getName()); 3080 XmlUtils.skipCurrentTag(parser); 3081 } 3082 } 3083 3084 str.close(); 3085 3086 } catch (XmlPullParserException e) { 3087 mReadMessages.append("Error reading: " + e.toString()); 3088 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 3089 Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); 3090 3091 } catch (java.io.IOException e) { 3092 mReadMessages.append("Error reading: " + e.toString()); 3093 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 3094 Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); 3095 } 3096 3097 // If the build is setup to drop runtime permissions 3098 // on update drop the files before loading them. 3099 if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) { 3100 final VersionInfo internal = getInternalVersion(); 3101 if (!Build.FINGERPRINT.equals(internal.fingerprint)) { 3102 for (UserInfo user : users) { 3103 mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id); 3104 } 3105 } 3106 } 3107 3108 final int N = mPendingPackages.size(); 3109 3110 for (int i = 0; i < N; i++) { 3111 final PackageSetting p = mPendingPackages.get(i); 3112 final int sharedUserId = p.getSharedUserId(); 3113 final Object idObj = getUserIdLPr(sharedUserId); 3114 if (idObj instanceof SharedUserSetting) { 3115 final SharedUserSetting sharedUser = (SharedUserSetting) idObj; 3116 p.sharedUser = sharedUser; 3117 p.appId = sharedUser.userId; 3118 addPackageSettingLPw(p, sharedUser); 3119 } else if (idObj != null) { 3120 String msg = "Bad package setting: package " + p.name + " has shared uid " 3121 + sharedUserId + " that is not a shared uid\n"; 3122 mReadMessages.append(msg); 3123 PackageManagerService.reportSettingsProblem(Log.ERROR, msg); 3124 } else { 3125 String msg = "Bad package setting: package " + p.name + " has shared uid " 3126 + sharedUserId + " that is not defined\n"; 3127 mReadMessages.append(msg); 3128 PackageManagerService.reportSettingsProblem(Log.ERROR, msg); 3129 } 3130 } 3131 mPendingPackages.clear(); 3132 3133 if (mBackupStoppedPackagesFilename.exists() 3134 || mStoppedPackagesFilename.exists()) { 3135 // Read old file 3136 readStoppedLPw(); 3137 mBackupStoppedPackagesFilename.delete(); 3138 mStoppedPackagesFilename.delete(); 3139 // Migrate to new file format 3140 writePackageRestrictionsLPr(UserHandle.USER_SYSTEM); 3141 } else { 3142 for (UserInfo user : users) { 3143 readPackageRestrictionsLPr(user.id); 3144 } 3145 } 3146 3147 for (UserInfo user : users) { 3148 mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id); 3149 } 3150 3151 /* 3152 * Make sure all the updated system packages have their shared users 3153 * associated with them. 3154 */ 3155 final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator(); 3156 while (disabledIt.hasNext()) { 3157 final PackageSetting disabledPs = disabledIt.next(); 3158 final Object id = getUserIdLPr(disabledPs.appId); 3159 if (id != null && id instanceof SharedUserSetting) { 3160 disabledPs.sharedUser = (SharedUserSetting) id; 3161 } 3162 } 3163 3164 mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, " 3165 + mSharedUsers.size() + " shared uids\n"); 3166 3167 writeKernelMappingLPr(); 3168 3169 return true; 3170 } 3171 3172 void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) { 3173 // First pull data from any pre-installed apps. 3174 for (PackageSetting ps : mPackages.values()) { 3175 if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null 3176 && ps.pkg.preferredActivityFilters != null) { 3177 ArrayList<PackageParser.ActivityIntentInfo> intents 3178 = ps.pkg.preferredActivityFilters; 3179 for (int i=0; i<intents.size(); i++) { 3180 PackageParser.ActivityIntentInfo aii = intents.get(i); 3181 applyDefaultPreferredActivityLPw(service, aii, new ComponentName( 3182 ps.name, aii.activity.className), userId); 3183 } 3184 } 3185 } 3186 3187 // Read preferred apps from .../etc/preferred-apps directory. 3188 File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps"); 3189 if (!preferredDir.exists() || !preferredDir.isDirectory()) { 3190 return; 3191 } 3192 if (!preferredDir.canRead()) { 3193 Slog.w(TAG, "Directory " + preferredDir + " cannot be read"); 3194 return; 3195 } 3196 3197 // Iterate over the files in the directory and scan .xml files 3198 for (File f : preferredDir.listFiles()) { 3199 if (!f.getPath().endsWith(".xml")) { 3200 Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring"); 3201 continue; 3202 } 3203 if (!f.canRead()) { 3204 Slog.w(TAG, "Preferred apps file " + f + " cannot be read"); 3205 continue; 3206 } 3207 3208 if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f); 3209 InputStream str = null; 3210 try { 3211 str = new BufferedInputStream(new FileInputStream(f)); 3212 XmlPullParser parser = Xml.newPullParser(); 3213 parser.setInput(str, null); 3214 3215 int type; 3216 while ((type = parser.next()) != XmlPullParser.START_TAG 3217 && type != XmlPullParser.END_DOCUMENT) { 3218 ; 3219 } 3220 3221 if (type != XmlPullParser.START_TAG) { 3222 Slog.w(TAG, "Preferred apps file " + f + " does not have start tag"); 3223 continue; 3224 } 3225 if (!"preferred-activities".equals(parser.getName())) { 3226 Slog.w(TAG, "Preferred apps file " + f 3227 + " does not start with 'preferred-activities'"); 3228 continue; 3229 } 3230 readDefaultPreferredActivitiesLPw(service, parser, userId); 3231 } catch (XmlPullParserException e) { 3232 Slog.w(TAG, "Error reading apps file " + f, e); 3233 } catch (IOException e) { 3234 Slog.w(TAG, "Error reading apps file " + f, e); 3235 } finally { 3236 if (str != null) { 3237 try { 3238 str.close(); 3239 } catch (IOException e) { 3240 } 3241 } 3242 } 3243 } 3244 } 3245 3246 private void applyDefaultPreferredActivityLPw(PackageManagerService service, 3247 IntentFilter tmpPa, ComponentName cn, int userId) { 3248 // The initial preferences only specify the target activity 3249 // component and intent-filter, not the set of matches. So we 3250 // now need to query for the matches to build the correct 3251 // preferred activity entry. 3252 if (PackageManagerService.DEBUG_PREFERRED) { 3253 Log.d(TAG, "Processing preferred:"); 3254 tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), " "); 3255 } 3256 Intent intent = new Intent(); 3257 int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE 3258 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 3259 intent.setAction(tmpPa.getAction(0)); 3260 for (int i=0; i<tmpPa.countCategories(); i++) { 3261 String cat = tmpPa.getCategory(i); 3262 if (cat.equals(Intent.CATEGORY_DEFAULT)) { 3263 flags |= MATCH_DEFAULT_ONLY; 3264 } else { 3265 intent.addCategory(cat); 3266 } 3267 } 3268 3269 boolean doNonData = true; 3270 boolean hasSchemes = false; 3271 3272 for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) { 3273 boolean doScheme = true; 3274 String scheme = tmpPa.getDataScheme(ischeme); 3275 if (scheme != null && !scheme.isEmpty()) { 3276 hasSchemes = true; 3277 } 3278 for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) { 3279 Uri.Builder builder = new Uri.Builder(); 3280 builder.scheme(scheme); 3281 PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp); 3282 builder.opaquePart(ssp.getPath()); 3283 Intent finalIntent = new Intent(intent); 3284 finalIntent.setData(builder.build()); 3285 applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn, 3286 scheme, ssp, null, null, userId); 3287 doScheme = false; 3288 } 3289 for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) { 3290 boolean doAuth = true; 3291 IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth); 3292 for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) { 3293 Uri.Builder builder = new Uri.Builder(); 3294 builder.scheme(scheme); 3295 if (auth.getHost() != null) { 3296 builder.authority(auth.getHost()); 3297 } 3298 PatternMatcher path = tmpPa.getDataPath(ipath); 3299 builder.path(path.getPath()); 3300 Intent finalIntent = new Intent(intent); 3301 finalIntent.setData(builder.build()); 3302 applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn, 3303 scheme, null, auth, path, userId); 3304 doAuth = doScheme = false; 3305 } 3306 if (doAuth) { 3307 Uri.Builder builder = new Uri.Builder(); 3308 builder.scheme(scheme); 3309 if (auth.getHost() != null) { 3310 builder.authority(auth.getHost()); 3311 } 3312 Intent finalIntent = new Intent(intent); 3313 finalIntent.setData(builder.build()); 3314 applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn, 3315 scheme, null, auth, null, userId); 3316 doScheme = false; 3317 } 3318 } 3319 if (doScheme) { 3320 Uri.Builder builder = new Uri.Builder(); 3321 builder.scheme(scheme); 3322 Intent finalIntent = new Intent(intent); 3323 finalIntent.setData(builder.build()); 3324 applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn, 3325 scheme, null, null, null, userId); 3326 } 3327 doNonData = false; 3328 } 3329 3330 for (int idata=0; idata<tmpPa.countDataTypes(); idata++) { 3331 String mimeType = tmpPa.getDataType(idata); 3332 if (hasSchemes) { 3333 Uri.Builder builder = new Uri.Builder(); 3334 for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) { 3335 String scheme = tmpPa.getDataScheme(ischeme); 3336 if (scheme != null && !scheme.isEmpty()) { 3337 Intent finalIntent = new Intent(intent); 3338 builder.scheme(scheme); 3339 finalIntent.setDataAndType(builder.build(), mimeType); 3340 applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn, 3341 scheme, null, null, null, userId); 3342 } 3343 } 3344 } else { 3345 Intent finalIntent = new Intent(intent); 3346 finalIntent.setType(mimeType); 3347 applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn, 3348 null, null, null, null, userId); 3349 } 3350 doNonData = false; 3351 } 3352 3353 if (doNonData) { 3354 applyDefaultPreferredActivityLPw(service, intent, flags, cn, 3355 null, null, null, null, userId); 3356 } 3357 } 3358 3359 private void applyDefaultPreferredActivityLPw(PackageManagerService service, 3360 Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp, 3361 IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) { 3362 flags = service.updateFlagsForResolve(flags, userId, intent, Binder.getCallingUid(), false); 3363 List<ResolveInfo> ri = service.mActivities.queryIntent(intent, 3364 intent.getType(), flags, 0); 3365 if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent 3366 + " results: " + ri); 3367 int systemMatch = 0; 3368 int thirdPartyMatch = 0; 3369 if (ri != null && ri.size() > 1) { 3370 boolean haveAct = false; 3371 ComponentName haveNonSys = null; 3372 ComponentName[] set = new ComponentName[ri.size()]; 3373 for (int i=0; i<ri.size(); i++) { 3374 ActivityInfo ai = ri.get(i).activityInfo; 3375 set[i] = new ComponentName(ai.packageName, ai.name); 3376 if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 3377 if (ri.get(i).match >= thirdPartyMatch) { 3378 // Keep track of the best match we find of all third 3379 // party apps, for use later to determine if we actually 3380 // want to set a preferred app for this intent. 3381 if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result " 3382 + ai.packageName + "/" + ai.name + ": non-system!"); 3383 haveNonSys = set[i]; 3384 break; 3385 } 3386 } else if (cn.getPackageName().equals(ai.packageName) 3387 && cn.getClassName().equals(ai.name)) { 3388 if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result " 3389 + ai.packageName + "/" + ai.name + ": default!"); 3390 haveAct = true; 3391 systemMatch = ri.get(i).match; 3392 } else { 3393 if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result " 3394 + ai.packageName + "/" + ai.name + ": skipped"); 3395 } 3396 } 3397 if (haveNonSys != null && thirdPartyMatch < systemMatch) { 3398 // If we have a matching third party app, but its match is not as 3399 // good as the built-in system app, then we don't want to actually 3400 // consider it a match because presumably the built-in app is still 3401 // the thing we want users to see by default. 3402 haveNonSys = null; 3403 } 3404 if (haveAct && haveNonSys == null) { 3405 IntentFilter filter = new IntentFilter(); 3406 if (intent.getAction() != null) { 3407 filter.addAction(intent.getAction()); 3408 } 3409 if (intent.getCategories() != null) { 3410 for (String cat : intent.getCategories()) { 3411 filter.addCategory(cat); 3412 } 3413 } 3414 if ((flags & MATCH_DEFAULT_ONLY) != 0) { 3415 filter.addCategory(Intent.CATEGORY_DEFAULT); 3416 } 3417 if (scheme != null) { 3418 filter.addDataScheme(scheme); 3419 } 3420 if (ssp != null) { 3421 filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType()); 3422 } 3423 if (auth != null) { 3424 filter.addDataAuthority(auth); 3425 } 3426 if (path != null) { 3427 filter.addDataPath(path); 3428 } 3429 if (intent.getType() != null) { 3430 try { 3431 filter.addDataType(intent.getType()); 3432 } catch (IntentFilter.MalformedMimeTypeException ex) { 3433 Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn); 3434 } 3435 } 3436 PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true); 3437 editPreferredActivitiesLPw(userId).addFilter(pa); 3438 } else if (haveNonSys == null) { 3439 StringBuilder sb = new StringBuilder(); 3440 sb.append("No component "); 3441 sb.append(cn.flattenToShortString()); 3442 sb.append(" found setting preferred "); 3443 sb.append(intent); 3444 sb.append("; possible matches are "); 3445 for (int i=0; i<set.length; i++) { 3446 if (i > 0) sb.append(", "); 3447 sb.append(set[i].flattenToShortString()); 3448 } 3449 Slog.w(TAG, sb.toString()); 3450 } else { 3451 Slog.i(TAG, "Not setting preferred " + intent + "; found third party match " 3452 + haveNonSys.flattenToShortString()); 3453 } 3454 } else { 3455 Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred " 3456 + cn.flattenToShortString()); 3457 } 3458 } 3459 3460 private void readDefaultPreferredActivitiesLPw(PackageManagerService service, 3461 XmlPullParser parser, int userId) 3462 throws XmlPullParserException, IOException { 3463 int outerDepth = parser.getDepth(); 3464 int type; 3465 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 3466 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 3467 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 3468 continue; 3469 } 3470 3471 String tagName = parser.getName(); 3472 if (tagName.equals(TAG_ITEM)) { 3473 PreferredActivity tmpPa = new PreferredActivity(parser); 3474 if (tmpPa.mPref.getParseError() == null) { 3475 applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent, 3476 userId); 3477 } else { 3478 PackageManagerService.reportSettingsProblem(Log.WARN, 3479 "Error in package manager settings: <preferred-activity> " 3480 + tmpPa.mPref.getParseError() + " at " 3481 + parser.getPositionDescription()); 3482 } 3483 } else { 3484 PackageManagerService.reportSettingsProblem(Log.WARN, 3485 "Unknown element under <preferred-activities>: " + parser.getName()); 3486 XmlUtils.skipCurrentTag(parser); 3487 } 3488 } 3489 } 3490 3491 private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException, 3492 IOException { 3493 String name = parser.getAttributeValue(null, ATTR_NAME); 3494 String realName = parser.getAttributeValue(null, "realName"); 3495 String codePathStr = parser.getAttributeValue(null, "codePath"); 3496 String resourcePathStr = parser.getAttributeValue(null, "resourcePath"); 3497 3498 String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi"); 3499 String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath"); 3500 3501 String parentPackageName = parser.getAttributeValue(null, "parentPackageName"); 3502 3503 String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi"); 3504 String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi"); 3505 String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride"); 3506 3507 if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) { 3508 primaryCpuAbiStr = legacyCpuAbiStr; 3509 } 3510 3511 if (resourcePathStr == null) { 3512 resourcePathStr = codePathStr; 3513 } 3514 String version = parser.getAttributeValue(null, "version"); 3515 long versionCode = 0; 3516 if (version != null) { 3517 try { 3518 versionCode = Long.parseLong(version); 3519 } catch (NumberFormatException e) { 3520 } 3521 } 3522 3523 int pkgFlags = 0; 3524 int pkgPrivateFlags = 0; 3525 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 3526 if (PackageManagerService.locationIsPrivileged(codePathStr)) { 3527 pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 3528 } 3529 PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), 3530 new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr, 3531 secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags, 3532 parentPackageName, null /*childPackageNames*/, 0 /*sharedUserId*/, null, null); 3533 String timeStampStr = parser.getAttributeValue(null, "ft"); 3534 if (timeStampStr != null) { 3535 try { 3536 long timeStamp = Long.parseLong(timeStampStr, 16); 3537 ps.setTimeStamp(timeStamp); 3538 } catch (NumberFormatException e) { 3539 } 3540 } else { 3541 timeStampStr = parser.getAttributeValue(null, "ts"); 3542 if (timeStampStr != null) { 3543 try { 3544 long timeStamp = Long.parseLong(timeStampStr); 3545 ps.setTimeStamp(timeStamp); 3546 } catch (NumberFormatException e) { 3547 } 3548 } 3549 } 3550 timeStampStr = parser.getAttributeValue(null, "it"); 3551 if (timeStampStr != null) { 3552 try { 3553 ps.firstInstallTime = Long.parseLong(timeStampStr, 16); 3554 } catch (NumberFormatException e) { 3555 } 3556 } 3557 timeStampStr = parser.getAttributeValue(null, "ut"); 3558 if (timeStampStr != null) { 3559 try { 3560 ps.lastUpdateTime = Long.parseLong(timeStampStr, 16); 3561 } catch (NumberFormatException e) { 3562 } 3563 } 3564 String idStr = parser.getAttributeValue(null, "userId"); 3565 ps.appId = idStr != null ? Integer.parseInt(idStr) : 0; 3566 if (ps.appId <= 0) { 3567 String sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); 3568 ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0; 3569 } 3570 3571 int outerDepth = parser.getDepth(); 3572 int type; 3573 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 3574 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 3575 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 3576 continue; 3577 } 3578 3579 if (parser.getName().equals(TAG_PERMISSIONS)) { 3580 readInstallPermissionsLPr(parser, ps.getPermissionsState()); 3581 } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) { 3582 String childPackageName = parser.getAttributeValue(null, ATTR_NAME); 3583 if (ps.childPackageNames == null) { 3584 ps.childPackageNames = new ArrayList<>(); 3585 } 3586 ps.childPackageNames.add(childPackageName); 3587 } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) { 3588 readUsesStaticLibLPw(parser, ps); 3589 } else { 3590 PackageManagerService.reportSettingsProblem(Log.WARN, 3591 "Unknown element under <updated-package>: " + parser.getName()); 3592 XmlUtils.skipCurrentTag(parser); 3593 } 3594 } 3595 3596 mDisabledSysPackages.put(name, ps); 3597 } 3598 3599 private static int PRE_M_APP_INFO_FLAG_HIDDEN = 1<<27; 3600 private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28; 3601 private static int PRE_M_APP_INFO_FLAG_FORWARD_LOCK = 1<<29; 3602 private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30; 3603 3604 private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException { 3605 String name = null; 3606 String realName = null; 3607 String idStr = null; 3608 String sharedIdStr = null; 3609 String codePathStr = null; 3610 String resourcePathStr = null; 3611 String legacyCpuAbiString = null; 3612 String legacyNativeLibraryPathStr = null; 3613 String primaryCpuAbiString = null; 3614 String secondaryCpuAbiString = null; 3615 String cpuAbiOverrideString = null; 3616 String systemStr = null; 3617 String installerPackageName = null; 3618 String isOrphaned = null; 3619 String volumeUuid = null; 3620 String categoryHintString = null; 3621 String updateAvailable = null; 3622 int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED; 3623 String uidError = null; 3624 int pkgFlags = 0; 3625 int pkgPrivateFlags = 0; 3626 long timeStamp = 0; 3627 long firstInstallTime = 0; 3628 long lastUpdateTime = 0; 3629 PackageSetting packageSetting = null; 3630 String version = null; 3631 long versionCode = 0; 3632 String parentPackageName; 3633 try { 3634 name = parser.getAttributeValue(null, ATTR_NAME); 3635 realName = parser.getAttributeValue(null, "realName"); 3636 idStr = parser.getAttributeValue(null, "userId"); 3637 uidError = parser.getAttributeValue(null, "uidError"); 3638 sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); 3639 codePathStr = parser.getAttributeValue(null, "codePath"); 3640 resourcePathStr = parser.getAttributeValue(null, "resourcePath"); 3641 3642 legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi"); 3643 3644 parentPackageName = parser.getAttributeValue(null, "parentPackageName"); 3645 3646 legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath"); 3647 primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi"); 3648 secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi"); 3649 cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride"); 3650 updateAvailable = parser.getAttributeValue(null, "updateAvailable"); 3651 3652 if (primaryCpuAbiString == null && legacyCpuAbiString != null) { 3653 primaryCpuAbiString = legacyCpuAbiString; 3654 } 3655 3656 version = parser.getAttributeValue(null, "version"); 3657 if (version != null) { 3658 try { 3659 versionCode = Long.parseLong(version); 3660 } catch (NumberFormatException e) { 3661 } 3662 } 3663 installerPackageName = parser.getAttributeValue(null, "installer"); 3664 isOrphaned = parser.getAttributeValue(null, "isOrphaned"); 3665 volumeUuid = parser.getAttributeValue(null, "volumeUuid"); 3666 categoryHintString = parser.getAttributeValue(null, "categoryHint"); 3667 if (categoryHintString != null) { 3668 try { 3669 categoryHint = Integer.parseInt(categoryHintString); 3670 } catch (NumberFormatException e) { 3671 } 3672 } 3673 3674 systemStr = parser.getAttributeValue(null, "publicFlags"); 3675 if (systemStr != null) { 3676 try { 3677 pkgFlags = Integer.parseInt(systemStr); 3678 } catch (NumberFormatException e) { 3679 } 3680 systemStr = parser.getAttributeValue(null, "privateFlags"); 3681 if (systemStr != null) { 3682 try { 3683 pkgPrivateFlags = Integer.parseInt(systemStr); 3684 } catch (NumberFormatException e) { 3685 } 3686 } 3687 } else { 3688 // Pre-M -- both public and private flags were stored in one "flags" field. 3689 systemStr = parser.getAttributeValue(null, "flags"); 3690 if (systemStr != null) { 3691 try { 3692 pkgFlags = Integer.parseInt(systemStr); 3693 } catch (NumberFormatException e) { 3694 } 3695 if ((pkgFlags & PRE_M_APP_INFO_FLAG_HIDDEN) != 0) { 3696 pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN; 3697 } 3698 if ((pkgFlags & PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE) != 0) { 3699 pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE; 3700 } 3701 if ((pkgFlags & PRE_M_APP_INFO_FLAG_FORWARD_LOCK) != 0) { 3702 pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK; 3703 } 3704 if ((pkgFlags & PRE_M_APP_INFO_FLAG_PRIVILEGED) != 0) { 3705 pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 3706 } 3707 pkgFlags &= ~(PRE_M_APP_INFO_FLAG_HIDDEN 3708 | PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE 3709 | PRE_M_APP_INFO_FLAG_FORWARD_LOCK 3710 | PRE_M_APP_INFO_FLAG_PRIVILEGED); 3711 } else { 3712 // For backward compatibility 3713 systemStr = parser.getAttributeValue(null, "system"); 3714 if (systemStr != null) { 3715 pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM 3716 : 0; 3717 } else { 3718 // Old settings that don't specify system... just treat 3719 // them as system, good enough. 3720 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 3721 } 3722 } 3723 } 3724 String timeStampStr = parser.getAttributeValue(null, "ft"); 3725 if (timeStampStr != null) { 3726 try { 3727 timeStamp = Long.parseLong(timeStampStr, 16); 3728 } catch (NumberFormatException e) { 3729 } 3730 } else { 3731 timeStampStr = parser.getAttributeValue(null, "ts"); 3732 if (timeStampStr != null) { 3733 try { 3734 timeStamp = Long.parseLong(timeStampStr); 3735 } catch (NumberFormatException e) { 3736 } 3737 } 3738 } 3739 timeStampStr = parser.getAttributeValue(null, "it"); 3740 if (timeStampStr != null) { 3741 try { 3742 firstInstallTime = Long.parseLong(timeStampStr, 16); 3743 } catch (NumberFormatException e) { 3744 } 3745 } 3746 timeStampStr = parser.getAttributeValue(null, "ut"); 3747 if (timeStampStr != null) { 3748 try { 3749 lastUpdateTime = Long.parseLong(timeStampStr, 16); 3750 } catch (NumberFormatException e) { 3751 } 3752 } 3753 if (PackageManagerService.DEBUG_SETTINGS) 3754 Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr 3755 + " sharedUserId=" + sharedIdStr); 3756 final int userId = idStr != null ? Integer.parseInt(idStr) : 0; 3757 final int sharedUserId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0; 3758 if (resourcePathStr == null) { 3759 resourcePathStr = codePathStr; 3760 } 3761 if (realName != null) { 3762 realName = realName.intern(); 3763 } 3764 if (name == null) { 3765 PackageManagerService.reportSettingsProblem(Log.WARN, 3766 "Error in package manager settings: <package> has no name at " 3767 + parser.getPositionDescription()); 3768 } else if (codePathStr == null) { 3769 PackageManagerService.reportSettingsProblem(Log.WARN, 3770 "Error in package manager settings: <package> has no codePath at " 3771 + parser.getPositionDescription()); 3772 } else if (userId > 0) { 3773 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr), 3774 new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString, 3775 secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags, 3776 pkgPrivateFlags, parentPackageName, null /*childPackageNames*/, 3777 null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/); 3778 if (PackageManagerService.DEBUG_SETTINGS) 3779 Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId=" 3780 + userId + " pkg=" + packageSetting); 3781 if (packageSetting == null) { 3782 PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid " 3783 + userId + " while parsing settings at " 3784 + parser.getPositionDescription()); 3785 } else { 3786 packageSetting.setTimeStamp(timeStamp); 3787 packageSetting.firstInstallTime = firstInstallTime; 3788 packageSetting.lastUpdateTime = lastUpdateTime; 3789 } 3790 } else if (sharedIdStr != null) { 3791 if (sharedUserId > 0) { 3792 packageSetting = new PackageSetting(name.intern(), realName, new File( 3793 codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr, 3794 primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, 3795 versionCode, pkgFlags, pkgPrivateFlags, parentPackageName, 3796 null /*childPackageNames*/, sharedUserId, 3797 null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/); 3798 packageSetting.setTimeStamp(timeStamp); 3799 packageSetting.firstInstallTime = firstInstallTime; 3800 packageSetting.lastUpdateTime = lastUpdateTime; 3801 mPendingPackages.add(packageSetting); 3802 if (PackageManagerService.DEBUG_SETTINGS) 3803 Log.i(PackageManagerService.TAG, "Reading package " + name 3804 + ": sharedUserId=" + sharedUserId + " pkg=" + packageSetting); 3805 } else { 3806 PackageManagerService.reportSettingsProblem(Log.WARN, 3807 "Error in package manager settings: package " + name 3808 + " has bad sharedId " + sharedIdStr + " at " 3809 + parser.getPositionDescription()); 3810 } 3811 } else { 3812 PackageManagerService.reportSettingsProblem(Log.WARN, 3813 "Error in package manager settings: package " + name + " has bad userId " 3814 + idStr + " at " + parser.getPositionDescription()); 3815 } 3816 } catch (NumberFormatException e) { 3817 PackageManagerService.reportSettingsProblem(Log.WARN, 3818 "Error in package manager settings: package " + name + " has bad userId " 3819 + idStr + " at " + parser.getPositionDescription()); 3820 } 3821 if (packageSetting != null) { 3822 packageSetting.uidError = "true".equals(uidError); 3823 packageSetting.installerPackageName = installerPackageName; 3824 packageSetting.isOrphaned = "true".equals(isOrphaned); 3825 packageSetting.volumeUuid = volumeUuid; 3826 packageSetting.categoryHint = categoryHint; 3827 packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr; 3828 packageSetting.primaryCpuAbiString = primaryCpuAbiString; 3829 packageSetting.secondaryCpuAbiString = secondaryCpuAbiString; 3830 packageSetting.updateAvailable = "true".equals(updateAvailable); 3831 // Handle legacy string here for single-user mode 3832 final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED); 3833 if (enabledStr != null) { 3834 try { 3835 packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null); 3836 } catch (NumberFormatException e) { 3837 if (enabledStr.equalsIgnoreCase("true")) { 3838 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null); 3839 } else if (enabledStr.equalsIgnoreCase("false")) { 3840 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null); 3841 } else if (enabledStr.equalsIgnoreCase("default")) { 3842 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null); 3843 } else { 3844 PackageManagerService.reportSettingsProblem(Log.WARN, 3845 "Error in package manager settings: package " + name 3846 + " has bad enabled value: " + idStr + " at " 3847 + parser.getPositionDescription()); 3848 } 3849 } 3850 } else { 3851 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null); 3852 } 3853 3854 if (installerPackageName != null) { 3855 mInstallerPackages.add(installerPackageName); 3856 } 3857 3858 final String installStatusStr = parser.getAttributeValue(null, "installStatus"); 3859 if (installStatusStr != null) { 3860 if (installStatusStr.equalsIgnoreCase("false")) { 3861 packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE; 3862 } else { 3863 packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE; 3864 } 3865 } 3866 3867 int outerDepth = parser.getDepth(); 3868 int type; 3869 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 3870 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 3871 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 3872 continue; 3873 } 3874 3875 String tagName = parser.getName(); 3876 // Legacy 3877 if (tagName.equals(TAG_DISABLED_COMPONENTS)) { 3878 readDisabledComponentsLPw(packageSetting, parser, 0); 3879 } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) { 3880 readEnabledComponentsLPw(packageSetting, parser, 0); 3881 } else if (tagName.equals("sigs")) { 3882 packageSetting.signatures.readXml(parser, mPastSignatures); 3883 } else if (tagName.equals(TAG_PERMISSIONS)) { 3884 readInstallPermissionsLPr(parser, 3885 packageSetting.getPermissionsState()); 3886 packageSetting.installPermissionsFixed = true; 3887 } else if (tagName.equals("proper-signing-keyset")) { 3888 long id = Long.parseLong(parser.getAttributeValue(null, "identifier")); 3889 Integer refCt = mKeySetRefs.get(id); 3890 if (refCt != null) { 3891 mKeySetRefs.put(id, refCt + 1); 3892 } else { 3893 mKeySetRefs.put(id, 1); 3894 } 3895 packageSetting.keySetData.setProperSigningKeySet(id); 3896 } else if (tagName.equals("signing-keyset")) { 3897 // from v1 of keysetmanagerservice - no longer used 3898 } else if (tagName.equals("upgrade-keyset")) { 3899 long id = Long.parseLong(parser.getAttributeValue(null, "identifier")); 3900 packageSetting.keySetData.addUpgradeKeySetById(id); 3901 } else if (tagName.equals("defined-keyset")) { 3902 long id = Long.parseLong(parser.getAttributeValue(null, "identifier")); 3903 String alias = parser.getAttributeValue(null, "alias"); 3904 Integer refCt = mKeySetRefs.get(id); 3905 if (refCt != null) { 3906 mKeySetRefs.put(id, refCt + 1); 3907 } else { 3908 mKeySetRefs.put(id, 1); 3909 } 3910 packageSetting.keySetData.addDefinedKeySet(id, alias); 3911 } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) { 3912 readDomainVerificationLPw(parser, packageSetting); 3913 } else if (tagName.equals(TAG_CHILD_PACKAGE)) { 3914 String childPackageName = parser.getAttributeValue(null, ATTR_NAME); 3915 if (packageSetting.childPackageNames == null) { 3916 packageSetting.childPackageNames = new ArrayList<>(); 3917 } 3918 packageSetting.childPackageNames.add(childPackageName); 3919 } else { 3920 PackageManagerService.reportSettingsProblem(Log.WARN, 3921 "Unknown element under <package>: " + parser.getName()); 3922 XmlUtils.skipCurrentTag(parser); 3923 } 3924 } 3925 } else { 3926 XmlUtils.skipCurrentTag(parser); 3927 } 3928 } 3929 3930 private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, 3931 int userId) throws IOException, XmlPullParserException { 3932 int outerDepth = parser.getDepth(); 3933 int type; 3934 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 3935 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 3936 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 3937 continue; 3938 } 3939 3940 String tagName = parser.getName(); 3941 if (tagName.equals(TAG_ITEM)) { 3942 String name = parser.getAttributeValue(null, ATTR_NAME); 3943 if (name != null) { 3944 packageSetting.addDisabledComponent(name.intern(), userId); 3945 } else { 3946 PackageManagerService.reportSettingsProblem(Log.WARN, 3947 "Error in package manager settings: <disabled-components> has" 3948 + " no name at " + parser.getPositionDescription()); 3949 } 3950 } else { 3951 PackageManagerService.reportSettingsProblem(Log.WARN, 3952 "Unknown element under <disabled-components>: " + parser.getName()); 3953 } 3954 XmlUtils.skipCurrentTag(parser); 3955 } 3956 } 3957 3958 private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, 3959 int userId) throws IOException, XmlPullParserException { 3960 int outerDepth = parser.getDepth(); 3961 int type; 3962 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 3963 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 3964 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 3965 continue; 3966 } 3967 3968 String tagName = parser.getName(); 3969 if (tagName.equals(TAG_ITEM)) { 3970 String name = parser.getAttributeValue(null, ATTR_NAME); 3971 if (name != null) { 3972 packageSetting.addEnabledComponent(name.intern(), userId); 3973 } else { 3974 PackageManagerService.reportSettingsProblem(Log.WARN, 3975 "Error in package manager settings: <enabled-components> has" 3976 + " no name at " + parser.getPositionDescription()); 3977 } 3978 } else { 3979 PackageManagerService.reportSettingsProblem(Log.WARN, 3980 "Unknown element under <enabled-components>: " + parser.getName()); 3981 } 3982 XmlUtils.skipCurrentTag(parser); 3983 } 3984 } 3985 3986 private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException { 3987 String name = null; 3988 String idStr = null; 3989 int pkgFlags = 0; 3990 int pkgPrivateFlags = 0; 3991 SharedUserSetting su = null; 3992 try { 3993 name = parser.getAttributeValue(null, ATTR_NAME); 3994 idStr = parser.getAttributeValue(null, "userId"); 3995 int userId = idStr != null ? Integer.parseInt(idStr) : 0; 3996 if ("true".equals(parser.getAttributeValue(null, "system"))) { 3997 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 3998 } 3999 if (name == null) { 4000 PackageManagerService.reportSettingsProblem(Log.WARN, 4001 "Error in package manager settings: <shared-user> has no name at " 4002 + parser.getPositionDescription()); 4003 } else if (userId == 0) { 4004 PackageManagerService.reportSettingsProblem(Log.WARN, 4005 "Error in package manager settings: shared-user " + name 4006 + " has bad userId " + idStr + " at " 4007 + parser.getPositionDescription()); 4008 } else { 4009 if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags)) 4010 == null) { 4011 PackageManagerService 4012 .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at " 4013 + parser.getPositionDescription()); 4014 } 4015 } 4016 } catch (NumberFormatException e) { 4017 PackageManagerService.reportSettingsProblem(Log.WARN, 4018 "Error in package manager settings: package " + name + " has bad userId " 4019 + idStr + " at " + parser.getPositionDescription()); 4020 } 4021 4022 if (su != null) { 4023 int outerDepth = parser.getDepth(); 4024 int type; 4025 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 4026 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 4027 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 4028 continue; 4029 } 4030 4031 String tagName = parser.getName(); 4032 if (tagName.equals("sigs")) { 4033 su.signatures.readXml(parser, mPastSignatures); 4034 } else if (tagName.equals("perms")) { 4035 readInstallPermissionsLPr(parser, su.getPermissionsState()); 4036 } else { 4037 PackageManagerService.reportSettingsProblem(Log.WARN, 4038 "Unknown element under <shared-user>: " + parser.getName()); 4039 XmlUtils.skipCurrentTag(parser); 4040 } 4041 } 4042 } else { 4043 XmlUtils.skipCurrentTag(parser); 4044 } 4045 } 4046 4047 void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer, 4048 int userHandle, String[] disallowedPackages) { 4049 String[] volumeUuids; 4050 String[] names; 4051 int[] appIds; 4052 String[] seinfos; 4053 int[] targetSdkVersions; 4054 int packagesCount; 4055 synchronized (mPackages) { 4056 Collection<PackageSetting> packages = mPackages.values(); 4057 packagesCount = packages.size(); 4058 volumeUuids = new String[packagesCount]; 4059 names = new String[packagesCount]; 4060 appIds = new int[packagesCount]; 4061 seinfos = new String[packagesCount]; 4062 targetSdkVersions = new int[packagesCount]; 4063 Iterator<PackageSetting> packagesIterator = packages.iterator(); 4064 for (int i = 0; i < packagesCount; i++) { 4065 PackageSetting ps = packagesIterator.next(); 4066 if (ps.pkg == null || ps.pkg.applicationInfo == null) { 4067 continue; 4068 } 4069 final boolean shouldInstall = ps.isSystem() && 4070 !ArrayUtils.contains(disallowedPackages, ps.name); 4071 // Only system apps are initially installed. 4072 ps.setInstalled(shouldInstall, userHandle); 4073 if (!shouldInstall) { 4074 writeKernelMappingLPr(ps); 4075 } 4076 // Need to create a data directory for all apps under this user. Accumulate all 4077 // required args and call the installer after mPackages lock has been released 4078 volumeUuids[i] = ps.volumeUuid; 4079 names[i] = ps.name; 4080 appIds[i] = ps.appId; 4081 seinfos[i] = ps.pkg.applicationInfo.seInfo; 4082 targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion; 4083 } 4084 } 4085 for (int i = 0; i < packagesCount; i++) { 4086 if (names[i] == null) { 4087 continue; 4088 } 4089 // TODO: triage flags! 4090 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 4091 try { 4092 installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i], 4093 seinfos[i], targetSdkVersions[i]); 4094 } catch (InstallerException e) { 4095 Slog.w(TAG, "Failed to prepare app data", e); 4096 } 4097 } 4098 synchronized (mPackages) { 4099 applyDefaultPreferredAppsLPw(service, userHandle); 4100 } 4101 } 4102 4103 void removeUserLPw(int userId) { 4104 Set<Entry<String, PackageSetting>> entries = mPackages.entrySet(); 4105 for (Entry<String, PackageSetting> entry : entries) { 4106 entry.getValue().removeUser(userId); 4107 } 4108 mPreferredActivities.remove(userId); 4109 File file = getUserPackagesStateFile(userId); 4110 file.delete(); 4111 file = getUserPackagesStateBackupFile(userId); 4112 file.delete(); 4113 removeCrossProfileIntentFiltersLPw(userId); 4114 4115 mRuntimePermissionsPersistence.onUserRemovedLPw(userId); 4116 4117 writePackageListLPr(); 4118 4119 // Inform kernel that the user was removed, so that packages are marked uninstalled 4120 // for sdcardfs 4121 writeKernelRemoveUserLPr(userId); 4122 } 4123 4124 void removeCrossProfileIntentFiltersLPw(int userId) { 4125 synchronized (mCrossProfileIntentResolvers) { 4126 // userId is the source user 4127 if (mCrossProfileIntentResolvers.get(userId) != null) { 4128 mCrossProfileIntentResolvers.remove(userId); 4129 writePackageRestrictionsLPr(userId); 4130 } 4131 // userId is the target user 4132 int count = mCrossProfileIntentResolvers.size(); 4133 for (int i = 0; i < count; i++) { 4134 int sourceUserId = mCrossProfileIntentResolvers.keyAt(i); 4135 CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId); 4136 boolean needsWriting = false; 4137 ArraySet<CrossProfileIntentFilter> cpifs = 4138 new ArraySet<CrossProfileIntentFilter>(cpir.filterSet()); 4139 for (CrossProfileIntentFilter cpif : cpifs) { 4140 if (cpif.getTargetUserId() == userId) { 4141 needsWriting = true; 4142 cpir.removeFilter(cpif); 4143 } 4144 } 4145 if (needsWriting) { 4146 writePackageRestrictionsLPr(sourceUserId); 4147 } 4148 } 4149 } 4150 } 4151 4152 // This should be called (at least) whenever an application is removed 4153 private void setFirstAvailableUid(int uid) { 4154 if (uid > mFirstAvailableUid) { 4155 mFirstAvailableUid = uid; 4156 } 4157 } 4158 4159 // Returns -1 if we could not find an available UserId to assign 4160 private int newUserIdLPw(Object obj) { 4161 // Let's be stupidly inefficient for now... 4162 final int N = mUserIds.size(); 4163 for (int i = mFirstAvailableUid; i < N; i++) { 4164 if (mUserIds.get(i) == null) { 4165 mUserIds.set(i, obj); 4166 return Process.FIRST_APPLICATION_UID + i; 4167 } 4168 } 4169 4170 // None left? 4171 if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) { 4172 return -1; 4173 } 4174 4175 mUserIds.add(obj); 4176 return Process.FIRST_APPLICATION_UID + N; 4177 } 4178 4179 public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() { 4180 if (mVerifierDeviceIdentity == null) { 4181 mVerifierDeviceIdentity = VerifierDeviceIdentity.generate(); 4182 4183 writeLPr(); 4184 } 4185 4186 return mVerifierDeviceIdentity; 4187 } 4188 4189 boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName, 4190 String childPackageName) { 4191 final int packageCount = mDisabledSysPackages.size(); 4192 for (int i = 0; i < packageCount; i++) { 4193 PackageSetting disabledPs = mDisabledSysPackages.valueAt(i); 4194 if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) { 4195 continue; 4196 } 4197 if (disabledPs.name.equals(parentPackageName)) { 4198 continue; 4199 } 4200 final int childCount = disabledPs.childPackageNames.size(); 4201 for (int j = 0; j < childCount; j++) { 4202 String currChildPackageName = disabledPs.childPackageNames.get(j); 4203 if (currChildPackageName.equals(childPackageName)) { 4204 return true; 4205 } 4206 } 4207 } 4208 return false; 4209 } 4210 4211 public PackageSetting getDisabledSystemPkgLPr(String name) { 4212 PackageSetting ps = mDisabledSysPackages.get(name); 4213 return ps; 4214 } 4215 4216 boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) { 4217 final PackageSetting ps = mPackages.get(componentInfo.packageName); 4218 if (ps == null) return false; 4219 4220 final PackageUserState userState = ps.readUserState(userId); 4221 return userState.isMatch(componentInfo, flags); 4222 } 4223 4224 String getInstallerPackageNameLPr(String packageName) { 4225 final PackageSetting pkg = mPackages.get(packageName); 4226 if (pkg == null) { 4227 throw new IllegalArgumentException("Unknown package: " + packageName); 4228 } 4229 return pkg.installerPackageName; 4230 } 4231 4232 boolean isOrphaned(String packageName) { 4233 final PackageSetting pkg = mPackages.get(packageName); 4234 if (pkg == null) { 4235 throw new IllegalArgumentException("Unknown package: " + packageName); 4236 } 4237 return pkg.isOrphaned; 4238 } 4239 4240 int getApplicationEnabledSettingLPr(String packageName, int userId) { 4241 final PackageSetting pkg = mPackages.get(packageName); 4242 if (pkg == null) { 4243 throw new IllegalArgumentException("Unknown package: " + packageName); 4244 } 4245 return pkg.getEnabled(userId); 4246 } 4247 4248 int getComponentEnabledSettingLPr(ComponentName componentName, int userId) { 4249 final String packageName = componentName.getPackageName(); 4250 final PackageSetting pkg = mPackages.get(packageName); 4251 if (pkg == null) { 4252 throw new IllegalArgumentException("Unknown component: " + componentName); 4253 } 4254 final String classNameStr = componentName.getClassName(); 4255 return pkg.getCurrentEnabledStateLPr(classNameStr, userId); 4256 } 4257 4258 boolean wasPackageEverLaunchedLPr(String packageName, int userId) { 4259 final PackageSetting pkgSetting = mPackages.get(packageName); 4260 if (pkgSetting == null) { 4261 throw new IllegalArgumentException("Unknown package: " + packageName); 4262 } 4263 return !pkgSetting.getNotLaunched(userId); 4264 } 4265 4266 boolean setPackageStoppedStateLPw(PackageManagerService pm, String packageName, 4267 boolean stopped, boolean allowedByPermission, int uid, int userId) { 4268 int appId = UserHandle.getAppId(uid); 4269 final PackageSetting pkgSetting = mPackages.get(packageName); 4270 if (pkgSetting == null) { 4271 throw new IllegalArgumentException("Unknown package: " + packageName); 4272 } 4273 if (!allowedByPermission && (appId != pkgSetting.appId)) { 4274 throw new SecurityException( 4275 "Permission Denial: attempt to change stopped state from pid=" 4276 + Binder.getCallingPid() 4277 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 4278 } 4279 if (DEBUG_STOPPED) { 4280 if (stopped) { 4281 RuntimeException e = new RuntimeException("here"); 4282 e.fillInStackTrace(); 4283 Slog.i(TAG, "Stopping package " + packageName, e); 4284 } 4285 } 4286 if (pkgSetting.getStopped(userId) != stopped) { 4287 pkgSetting.setStopped(stopped, userId); 4288 // pkgSetting.pkg.mSetStopped = stopped; 4289 if (pkgSetting.getNotLaunched(userId)) { 4290 if (pkgSetting.installerPackageName != null) { 4291 pm.notifyFirstLaunch(pkgSetting.name, pkgSetting.installerPackageName, userId); 4292 } 4293 pkgSetting.setNotLaunched(false, userId); 4294 } 4295 return true; 4296 } 4297 return false; 4298 } 4299 4300 private static List<UserInfo> getAllUsers(UserManagerService userManager) { 4301 long id = Binder.clearCallingIdentity(); 4302 try { 4303 return userManager.getUsers(false); 4304 } catch (NullPointerException npe) { 4305 // packagemanager not yet initialized 4306 } finally { 4307 Binder.restoreCallingIdentity(id); 4308 } 4309 return null; 4310 } 4311 4312 /** 4313 * Return all {@link PackageSetting} that are actively installed on the 4314 * given {@link VolumeInfo#fsUuid}. 4315 */ 4316 List<PackageSetting> getVolumePackagesLPr(String volumeUuid) { 4317 ArrayList<PackageSetting> res = new ArrayList<>(); 4318 for (int i = 0; i < mPackages.size(); i++) { 4319 final PackageSetting setting = mPackages.valueAt(i); 4320 if (Objects.equals(volumeUuid, setting.volumeUuid)) { 4321 res.add(setting); 4322 } 4323 } 4324 return res; 4325 } 4326 4327 static void printFlags(PrintWriter pw, int val, Object[] spec) { 4328 pw.print("[ "); 4329 for (int i=0; i<spec.length; i+=2) { 4330 int mask = (Integer)spec[i]; 4331 if ((val & mask) != 0) { 4332 pw.print(spec[i+1]); 4333 pw.print(" "); 4334 } 4335 } 4336 pw.print("]"); 4337 } 4338 4339 static final Object[] FLAG_DUMP_SPEC = new Object[] { 4340 ApplicationInfo.FLAG_SYSTEM, "SYSTEM", 4341 ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE", 4342 ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE", 4343 ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT", 4344 ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST", 4345 ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING", 4346 ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA", 4347 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP", 4348 ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY", 4349 ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE", 4350 ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP", 4351 ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE", 4352 ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION", 4353 ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE", 4354 ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP", 4355 }; 4356 4357 private static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] { 4358 ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE", 4359 ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION", 4360 ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE", 4361 ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND", 4362 ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE", 4363 ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE", 4364 ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE", 4365 ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK", 4366 ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS", 4367 ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN", 4368 ApplicationInfo.PRIVATE_FLAG_INSTANT, "EPHEMERAL", 4369 ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, "ISOLATED_SPLIT_LOADING", 4370 ApplicationInfo.PRIVATE_FLAG_OEM, "OEM", 4371 ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE", 4372 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED", 4373 ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER", 4374 ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY", 4375 ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR", 4376 ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD", 4377 }; 4378 4379 void dumpVersionLPr(IndentingPrintWriter pw) { 4380 pw.increaseIndent(); 4381 for (int i= 0; i < mVersion.size(); i++) { 4382 final String volumeUuid = mVersion.keyAt(i); 4383 final VersionInfo ver = mVersion.valueAt(i); 4384 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 4385 pw.println("Internal:"); 4386 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 4387 pw.println("External:"); 4388 } else { 4389 pw.println("UUID " + volumeUuid + ":"); 4390 } 4391 pw.increaseIndent(); 4392 pw.printPair("sdkVersion", ver.sdkVersion); 4393 pw.printPair("databaseVersion", ver.databaseVersion); 4394 pw.println(); 4395 pw.printPair("fingerprint", ver.fingerprint); 4396 pw.println(); 4397 pw.decreaseIndent(); 4398 } 4399 pw.decreaseIndent(); 4400 } 4401 4402 void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, 4403 ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, 4404 Date date, List<UserInfo> users, boolean dumpAll) { 4405 if (checkinTag != null) { 4406 pw.print(checkinTag); 4407 pw.print(","); 4408 pw.print(ps.realName != null ? ps.realName : ps.name); 4409 pw.print(","); 4410 pw.print(ps.appId); 4411 pw.print(","); 4412 pw.print(ps.versionCode); 4413 pw.print(","); 4414 pw.print(ps.firstInstallTime); 4415 pw.print(","); 4416 pw.print(ps.lastUpdateTime); 4417 pw.print(","); 4418 pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?"); 4419 pw.println(); 4420 if (ps.pkg != null) { 4421 pw.print(checkinTag); pw.print("-"); pw.print("splt,"); 4422 pw.print("base,"); 4423 pw.println(ps.pkg.baseRevisionCode); 4424 if (ps.pkg.splitNames != null) { 4425 for (int i = 0; i < ps.pkg.splitNames.length; i++) { 4426 pw.print(checkinTag); pw.print("-"); pw.print("splt,"); 4427 pw.print(ps.pkg.splitNames[i]); pw.print(","); 4428 pw.println(ps.pkg.splitRevisionCodes[i]); 4429 } 4430 } 4431 } 4432 for (UserInfo user : users) { 4433 pw.print(checkinTag); 4434 pw.print("-"); 4435 pw.print("usr"); 4436 pw.print(","); 4437 pw.print(user.id); 4438 pw.print(","); 4439 pw.print(ps.getInstalled(user.id) ? "I" : "i"); 4440 pw.print(ps.getHidden(user.id) ? "B" : "b"); 4441 pw.print(ps.getSuspended(user.id) ? "SU" : "su"); 4442 pw.print(ps.getStopped(user.id) ? "S" : "s"); 4443 pw.print(ps.getNotLaunched(user.id) ? "l" : "L"); 4444 pw.print(ps.getInstantApp(user.id) ? "IA" : "ia"); 4445 pw.print(ps.getVirtulalPreload(user.id) ? "VPI" : "vpi"); 4446 pw.print(","); 4447 pw.print(ps.getEnabled(user.id)); 4448 String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id); 4449 pw.print(","); 4450 pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?"); 4451 pw.println(); 4452 } 4453 return; 4454 } 4455 4456 pw.print(prefix); pw.print("Package ["); 4457 pw.print(ps.realName != null ? ps.realName : ps.name); 4458 pw.print("] ("); 4459 pw.print(Integer.toHexString(System.identityHashCode(ps))); 4460 pw.println("):"); 4461 4462 if (ps.realName != null) { 4463 pw.print(prefix); pw.print(" compat name="); 4464 pw.println(ps.name); 4465 } 4466 4467 pw.print(prefix); pw.print(" userId="); pw.println(ps.appId); 4468 4469 if (ps.sharedUser != null) { 4470 pw.print(prefix); pw.print(" sharedUser="); pw.println(ps.sharedUser); 4471 } 4472 pw.print(prefix); pw.print(" pkg="); pw.println(ps.pkg); 4473 pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString); 4474 if (permissionNames == null) { 4475 pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString); 4476 pw.print(prefix); pw.print(" legacyNativeLibraryDir="); 4477 pw.println(ps.legacyNativeLibraryPathString); 4478 pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString); 4479 pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString); 4480 } 4481 pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode); 4482 if (ps.pkg != null) { 4483 pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion); 4484 pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion); 4485 } 4486 pw.println(); 4487 if (ps.pkg != null) { 4488 if (ps.pkg.parentPackage != null) { 4489 PackageParser.Package parentPkg = ps.pkg.parentPackage; 4490 PackageSetting pps = mPackages.get(parentPkg.packageName); 4491 if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) { 4492 pps = mDisabledSysPackages.get(parentPkg.packageName); 4493 } 4494 if (pps != null) { 4495 pw.print(prefix); pw.print(" parentPackage="); 4496 pw.println(pps.realName != null ? pps.realName : pps.name); 4497 } 4498 } else if (ps.pkg.childPackages != null) { 4499 pw.print(prefix); pw.print(" childPackages=["); 4500 final int childCount = ps.pkg.childPackages.size(); 4501 for (int i = 0; i < childCount; i++) { 4502 PackageParser.Package childPkg = ps.pkg.childPackages.get(i); 4503 PackageSetting cps = mPackages.get(childPkg.packageName); 4504 if (cps == null || !cps.codePathString.equals(childPkg.codePath)) { 4505 cps = mDisabledSysPackages.get(childPkg.packageName); 4506 } 4507 if (cps != null) { 4508 if (i > 0) { 4509 pw.print(", "); 4510 } 4511 pw.print(cps.realName != null ? cps.realName : cps.name); 4512 } 4513 } 4514 pw.println("]"); 4515 } 4516 pw.print(prefix); pw.print(" versionName="); pw.println(ps.pkg.mVersionName); 4517 pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, ps.pkg); pw.println(); 4518 final int apkSigningVersion = ps.pkg.mSigningDetails.signatureSchemeVersion; 4519 pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion); 4520 pw.print(prefix); pw.print(" applicationInfo="); 4521 pw.println(ps.pkg.applicationInfo.toString()); 4522 pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags, 4523 FLAG_DUMP_SPEC); pw.println(); 4524 if (ps.pkg.applicationInfo.privateFlags != 0) { 4525 pw.print(prefix); pw.print(" privateFlags="); printFlags(pw, 4526 ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println(); 4527 } 4528 pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.applicationInfo.dataDir); 4529 pw.print(prefix); pw.print(" supportsScreens=["); 4530 boolean first = true; 4531 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) { 4532 if (!first) 4533 pw.print(", "); 4534 first = false; 4535 pw.print("small"); 4536 } 4537 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) { 4538 if (!first) 4539 pw.print(", "); 4540 first = false; 4541 pw.print("medium"); 4542 } 4543 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { 4544 if (!first) 4545 pw.print(", "); 4546 first = false; 4547 pw.print("large"); 4548 } 4549 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { 4550 if (!first) 4551 pw.print(", "); 4552 first = false; 4553 pw.print("xlarge"); 4554 } 4555 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { 4556 if (!first) 4557 pw.print(", "); 4558 first = false; 4559 pw.print("resizeable"); 4560 } 4561 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { 4562 if (!first) 4563 pw.print(", "); 4564 first = false; 4565 pw.print("anyDensity"); 4566 } 4567 pw.println("]"); 4568 if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) { 4569 pw.print(prefix); pw.println(" dynamic libraries:"); 4570 for (int i = 0; i<ps.pkg.libraryNames.size(); i++) { 4571 pw.print(prefix); pw.print(" "); 4572 pw.println(ps.pkg.libraryNames.get(i)); 4573 } 4574 } 4575 if (ps.pkg.staticSharedLibName != null) { 4576 pw.print(prefix); pw.println(" static library:"); 4577 pw.print(prefix); pw.print(" "); 4578 pw.print("name:"); pw.print(ps.pkg.staticSharedLibName); 4579 pw.print(" version:"); pw.println(ps.pkg.staticSharedLibVersion); 4580 } 4581 if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) { 4582 pw.print(prefix); pw.println(" usesLibraries:"); 4583 for (int i=0; i<ps.pkg.usesLibraries.size(); i++) { 4584 pw.print(prefix); pw.print(" "); pw.println(ps.pkg.usesLibraries.get(i)); 4585 } 4586 } 4587 if (ps.pkg.usesStaticLibraries != null 4588 && ps.pkg.usesStaticLibraries.size() > 0) { 4589 pw.print(prefix); pw.println(" usesStaticLibraries:"); 4590 for (int i=0; i<ps.pkg.usesStaticLibraries.size(); i++) { 4591 pw.print(prefix); pw.print(" "); 4592 pw.print(ps.pkg.usesStaticLibraries.get(i)); pw.print(" version:"); 4593 pw.println(ps.pkg.usesStaticLibrariesVersions[i]); 4594 } 4595 } 4596 if (ps.pkg.usesOptionalLibraries != null 4597 && ps.pkg.usesOptionalLibraries.size() > 0) { 4598 pw.print(prefix); pw.println(" usesOptionalLibraries:"); 4599 for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) { 4600 pw.print(prefix); pw.print(" "); 4601 pw.println(ps.pkg.usesOptionalLibraries.get(i)); 4602 } 4603 } 4604 if (ps.pkg.usesLibraryFiles != null 4605 && ps.pkg.usesLibraryFiles.length > 0) { 4606 pw.print(prefix); pw.println(" usesLibraryFiles:"); 4607 for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) { 4608 pw.print(prefix); pw.print(" "); pw.println(ps.pkg.usesLibraryFiles[i]); 4609 } 4610 } 4611 } 4612 pw.print(prefix); pw.print(" timeStamp="); 4613 date.setTime(ps.timeStamp); 4614 pw.println(sdf.format(date)); 4615 pw.print(prefix); pw.print(" firstInstallTime="); 4616 date.setTime(ps.firstInstallTime); 4617 pw.println(sdf.format(date)); 4618 pw.print(prefix); pw.print(" lastUpdateTime="); 4619 date.setTime(ps.lastUpdateTime); 4620 pw.println(sdf.format(date)); 4621 if (ps.installerPackageName != null) { 4622 pw.print(prefix); pw.print(" installerPackageName="); 4623 pw.println(ps.installerPackageName); 4624 } 4625 if (ps.volumeUuid != null) { 4626 pw.print(prefix); pw.print(" volumeUuid="); 4627 pw.println(ps.volumeUuid); 4628 } 4629 pw.print(prefix); pw.print(" signatures="); pw.println(ps.signatures); 4630 pw.print(prefix); pw.print(" installPermissionsFixed="); 4631 pw.print(ps.installPermissionsFixed); 4632 pw.print(" installStatus="); pw.println(ps.installStatus); 4633 pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC); 4634 pw.println(); 4635 4636 if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) { 4637 final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions; 4638 pw.print(prefix); pw.println(" declared permissions:"); 4639 for (int i=0; i<perms.size(); i++) { 4640 PackageParser.Permission perm = perms.get(i); 4641 if (permissionNames != null 4642 && !permissionNames.contains(perm.info.name)) { 4643 continue; 4644 } 4645 pw.print(prefix); pw.print(" "); pw.print(perm.info.name); 4646 pw.print(": prot="); 4647 pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel)); 4648 if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) { 4649 pw.print(", COSTS_MONEY"); 4650 } 4651 if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) { 4652 pw.print(", HIDDEN"); 4653 } 4654 if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) { 4655 pw.print(", INSTALLED"); 4656 } 4657 pw.println(); 4658 } 4659 } 4660 4661 if ((permissionNames != null || dumpAll) && ps.pkg != null 4662 && ps.pkg.requestedPermissions != null 4663 && ps.pkg.requestedPermissions.size() > 0) { 4664 final ArrayList<String> perms = ps.pkg.requestedPermissions; 4665 pw.print(prefix); pw.println(" requested permissions:"); 4666 for (int i=0; i<perms.size(); i++) { 4667 String perm = perms.get(i); 4668 if (permissionNames != null 4669 && !permissionNames.contains(perm)) { 4670 continue; 4671 } 4672 pw.print(prefix); pw.print(" "); pw.println(perm); 4673 } 4674 } 4675 4676 if (ps.sharedUser == null || permissionNames != null || dumpAll) { 4677 PermissionsState permissionsState = ps.getPermissionsState(); 4678 dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState); 4679 } 4680 4681 for (UserInfo user : users) { 4682 pw.print(prefix); pw.print(" User "); pw.print(user.id); pw.print(": "); 4683 pw.print("ceDataInode="); 4684 pw.print(ps.getCeDataInode(user.id)); 4685 pw.print(" installed="); 4686 pw.print(ps.getInstalled(user.id)); 4687 pw.print(" hidden="); 4688 pw.print(ps.getHidden(user.id)); 4689 pw.print(" suspended="); 4690 pw.print(ps.getSuspended(user.id)); 4691 pw.print(" stopped="); 4692 pw.print(ps.getStopped(user.id)); 4693 pw.print(" notLaunched="); 4694 pw.print(ps.getNotLaunched(user.id)); 4695 pw.print(" enabled="); 4696 pw.print(ps.getEnabled(user.id)); 4697 pw.print(" instant="); 4698 pw.print(ps.getInstantApp(user.id)); 4699 pw.print(" virtual="); 4700 pw.println(ps.getVirtulalPreload(user.id)); 4701 4702 String[] overlayPaths = ps.getOverlayPaths(user.id); 4703 if (overlayPaths != null && overlayPaths.length > 0) { 4704 pw.print(prefix); pw.println(" overlay paths:"); 4705 for (String path : overlayPaths) { 4706 pw.print(prefix); pw.print(" "); pw.println(path); 4707 } 4708 } 4709 4710 String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id); 4711 if (lastDisabledAppCaller != null) { 4712 pw.print(prefix); pw.print(" lastDisabledCaller: "); 4713 pw.println(lastDisabledAppCaller); 4714 } 4715 4716 if (ps.sharedUser == null) { 4717 PermissionsState permissionsState = ps.getPermissionsState(); 4718 dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id)); 4719 dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState 4720 .getRuntimePermissionStates(user.id), dumpAll); 4721 } 4722 4723 if (permissionNames == null) { 4724 ArraySet<String> cmp = ps.getDisabledComponents(user.id); 4725 if (cmp != null && cmp.size() > 0) { 4726 pw.print(prefix); pw.println(" disabledComponents:"); 4727 for (String s : cmp) { 4728 pw.print(prefix); pw.print(" "); pw.println(s); 4729 } 4730 } 4731 cmp = ps.getEnabledComponents(user.id); 4732 if (cmp != null && cmp.size() > 0) { 4733 pw.print(prefix); pw.println(" enabledComponents:"); 4734 for (String s : cmp) { 4735 pw.print(prefix); pw.print(" "); pw.println(s); 4736 } 4737 } 4738 } 4739 } 4740 } 4741 4742 void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, 4743 DumpState dumpState, boolean checkin) { 4744 final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 4745 final Date date = new Date(); 4746 boolean printedSomething = false; 4747 List<UserInfo> users = getAllUsers(UserManagerService.getInstance()); 4748 for (final PackageSetting ps : mPackages.values()) { 4749 if (packageName != null && !packageName.equals(ps.realName) 4750 && !packageName.equals(ps.name)) { 4751 continue; 4752 } 4753 if (permissionNames != null 4754 && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) { 4755 continue; 4756 } 4757 4758 if (!checkin && packageName != null) { 4759 dumpState.setSharedUser(ps.sharedUser); 4760 } 4761 4762 if (!checkin && !printedSomething) { 4763 if (dumpState.onTitlePrinted()) 4764 pw.println(); 4765 pw.println("Packages:"); 4766 printedSomething = true; 4767 } 4768 dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users, 4769 packageName != null); 4770 } 4771 4772 printedSomething = false; 4773 if (mRenamedPackages.size() > 0 && permissionNames == null) { 4774 for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) { 4775 if (packageName != null && !packageName.equals(e.getKey()) 4776 && !packageName.equals(e.getValue())) { 4777 continue; 4778 } 4779 if (!checkin) { 4780 if (!printedSomething) { 4781 if (dumpState.onTitlePrinted()) 4782 pw.println(); 4783 pw.println("Renamed packages:"); 4784 printedSomething = true; 4785 } 4786 pw.print(" "); 4787 } else { 4788 pw.print("ren,"); 4789 } 4790 pw.print(e.getKey()); 4791 pw.print(checkin ? " -> " : ","); 4792 pw.println(e.getValue()); 4793 } 4794 } 4795 4796 printedSomething = false; 4797 if (mDisabledSysPackages.size() > 0 && permissionNames == null) { 4798 for (final PackageSetting ps : mDisabledSysPackages.values()) { 4799 if (packageName != null && !packageName.equals(ps.realName) 4800 && !packageName.equals(ps.name)) { 4801 continue; 4802 } 4803 if (!checkin && !printedSomething) { 4804 if (dumpState.onTitlePrinted()) 4805 pw.println(); 4806 pw.println("Hidden system packages:"); 4807 printedSomething = true; 4808 } 4809 dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date, 4810 users, packageName != null); 4811 } 4812 } 4813 } 4814 4815 void dumpPackagesProto(ProtoOutputStream proto) { 4816 List<UserInfo> users = getAllUsers(UserManagerService.getInstance()); 4817 4818 final int count = mPackages.size(); 4819 for (int i = 0; i < count; i++) { 4820 final PackageSetting ps = mPackages.valueAt(i); 4821 ps.writeToProto(proto, PackageServiceDumpProto.PACKAGES, users); 4822 } 4823 } 4824 4825 void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, 4826 DumpState dumpState) { 4827 mPermissions.dumpPermissions(pw, packageName, permissionNames, 4828 (mReadExternalStorageEnforced == Boolean.TRUE), dumpState); 4829 } 4830 4831 void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, 4832 DumpState dumpState, boolean checkin) { 4833 boolean printedSomething = false; 4834 for (SharedUserSetting su : mSharedUsers.values()) { 4835 if (packageName != null && su != dumpState.getSharedUser()) { 4836 continue; 4837 } 4838 if (permissionNames != null 4839 && !su.getPermissionsState().hasRequestedPermission(permissionNames)) { 4840 continue; 4841 } 4842 if (!checkin) { 4843 if (!printedSomething) { 4844 if (dumpState.onTitlePrinted()) 4845 pw.println(); 4846 pw.println("Shared users:"); 4847 printedSomething = true; 4848 } 4849 pw.print(" SharedUser ["); 4850 pw.print(su.name); 4851 pw.print("] ("); 4852 pw.print(Integer.toHexString(System.identityHashCode(su))); 4853 pw.println("):"); 4854 4855 String prefix = " "; 4856 pw.print(prefix); pw.print("userId="); pw.println(su.userId); 4857 4858 PermissionsState permissionsState = su.getPermissionsState(); 4859 dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState); 4860 4861 for (int userId : UserManagerService.getInstance().getUserIds()) { 4862 final int[] gids = permissionsState.computeGids(userId); 4863 List<PermissionState> permissions = permissionsState 4864 .getRuntimePermissionStates(userId); 4865 if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) { 4866 pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": "); 4867 dumpGidsLPr(pw, prefix + " ", gids); 4868 dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions, 4869 packageName != null); 4870 } 4871 } 4872 } else { 4873 pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name); 4874 } 4875 } 4876 } 4877 4878 void dumpSharedUsersProto(ProtoOutputStream proto) { 4879 final int count = mSharedUsers.size(); 4880 for (int i = 0; i < count; i++) { 4881 mSharedUsers.valueAt(i).writeToProto(proto, PackageServiceDumpProto.SHARED_USERS); 4882 } 4883 } 4884 4885 void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) { 4886 pw.println("Settings parse messages:"); 4887 pw.print(mReadMessages.toString()); 4888 } 4889 4890 void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) { 4891 if (mRestoredUserGrants.size() > 0) { 4892 pw.println(); 4893 pw.println("Restored (pending) permission grants:"); 4894 for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) { 4895 ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage = 4896 mRestoredUserGrants.valueAt(userIndex); 4897 if (grantsByPackage != null && grantsByPackage.size() > 0) { 4898 final int userId = mRestoredUserGrants.keyAt(userIndex); 4899 pw.print(" User "); pw.println(userId); 4900 4901 for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) { 4902 ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex); 4903 if (grants != null && grants.size() > 0) { 4904 final String pkgName = grantsByPackage.keyAt(pkgIndex); 4905 pw.print(" "); pw.print(pkgName); pw.println(" :"); 4906 4907 for (RestoredPermissionGrant g : grants) { 4908 pw.print(" "); 4909 pw.print(g.permissionName); 4910 if (g.granted) { 4911 pw.print(" GRANTED"); 4912 } 4913 if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) { 4914 pw.print(" user_set"); 4915 } 4916 if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) { 4917 pw.print(" user_fixed"); 4918 } 4919 if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) { 4920 pw.print(" revoke_on_upgrade"); 4921 } 4922 pw.println(); 4923 } 4924 } 4925 } 4926 } 4927 } 4928 pw.println(); 4929 } 4930 } 4931 4932 private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) { 4933 if (pkg == null) { 4934 pw.print("unknown"); 4935 } else { 4936 // [base:10, config.mdpi, config.xhdpi:12] 4937 pw.print("["); 4938 pw.print("base"); 4939 if (pkg.baseRevisionCode != 0) { 4940 pw.print(":"); pw.print(pkg.baseRevisionCode); 4941 } 4942 if (pkg.splitNames != null) { 4943 for (int i = 0; i < pkg.splitNames.length; i++) { 4944 pw.print(", "); 4945 pw.print(pkg.splitNames[i]); 4946 if (pkg.splitRevisionCodes[i] != 0) { 4947 pw.print(":"); pw.print(pkg.splitRevisionCodes[i]); 4948 } 4949 } 4950 } 4951 pw.print("]"); 4952 } 4953 } 4954 4955 void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) { 4956 if (!ArrayUtils.isEmpty(gids)) { 4957 pw.print(prefix); 4958 pw.print("gids="); pw.println( 4959 PackageManagerService.arrayToString(gids)); 4960 } 4961 } 4962 4963 void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, 4964 List<PermissionState> permissionStates, boolean dumpAll) { 4965 if (!permissionStates.isEmpty() || dumpAll) { 4966 pw.print(prefix); pw.println("runtime permissions:"); 4967 for (PermissionState permissionState : permissionStates) { 4968 if (permissionNames != null 4969 && !permissionNames.contains(permissionState.getName())) { 4970 continue; 4971 } 4972 pw.print(prefix); pw.print(" "); pw.print(permissionState.getName()); 4973 pw.print(": granted="); pw.print(permissionState.isGranted()); 4974 pw.println(permissionFlagsToString(", flags=", 4975 permissionState.getFlags())); 4976 } 4977 } 4978 } 4979 4980 private static String permissionFlagsToString(String prefix, int flags) { 4981 StringBuilder flagsString = null; 4982 while (flags != 0) { 4983 if (flagsString == null) { 4984 flagsString = new StringBuilder(); 4985 flagsString.append(prefix); 4986 flagsString.append("[ "); 4987 } 4988 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 4989 flags &= ~flag; 4990 flagsString.append(PackageManager.permissionFlagToString(flag)); 4991 flagsString.append(' '); 4992 } 4993 if (flagsString != null) { 4994 flagsString.append(']'); 4995 return flagsString.toString(); 4996 } else { 4997 return ""; 4998 } 4999 } 5000 5001 void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, 5002 PermissionsState permissionsState) { 5003 List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates(); 5004 if (!permissionStates.isEmpty()) { 5005 pw.print(prefix); pw.println("install permissions:"); 5006 for (PermissionState permissionState : permissionStates) { 5007 if (permissionNames != null 5008 && !permissionNames.contains(permissionState.getName())) { 5009 continue; 5010 } 5011 pw.print(prefix); pw.print(" "); pw.print(permissionState.getName()); 5012 pw.print(": granted="); pw.print(permissionState.isGranted()); 5013 pw.println(permissionFlagsToString(", flags=", 5014 permissionState.getFlags())); 5015 } 5016 } 5017 } 5018 5019 public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) { 5020 if (sync) { 5021 mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId); 5022 } else { 5023 mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId); 5024 } 5025 } 5026 5027 private final class RuntimePermissionPersistence { 5028 private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200; 5029 private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000; 5030 5031 private final Handler mHandler = new MyHandler(); 5032 5033 private final Object mPersistenceLock; 5034 5035 @GuardedBy("mLock") 5036 private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray(); 5037 5038 @GuardedBy("mLock") 5039 // The mapping keys are user ids. 5040 private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray(); 5041 5042 @GuardedBy("mLock") 5043 // The mapping keys are user ids. 5044 private final SparseArray<String> mFingerprints = new SparseArray<>(); 5045 5046 @GuardedBy("mLock") 5047 // The mapping keys are user ids. 5048 private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray(); 5049 5050 public RuntimePermissionPersistence(Object persistenceLock) { 5051 mPersistenceLock = persistenceLock; 5052 } 5053 5054 public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) { 5055 return mDefaultPermissionsGranted.get(userId); 5056 } 5057 5058 public void onDefaultRuntimePermissionsGrantedLPr(int userId) { 5059 mFingerprints.put(userId, Build.FINGERPRINT); 5060 writePermissionsForUserAsyncLPr(userId); 5061 } 5062 5063 public void writePermissionsForUserSyncLPr(int userId) { 5064 mHandler.removeMessages(userId); 5065 writePermissionsSync(userId); 5066 } 5067 5068 public void writePermissionsForUserAsyncLPr(int userId) { 5069 final long currentTimeMillis = SystemClock.uptimeMillis(); 5070 5071 if (mWriteScheduled.get(userId)) { 5072 mHandler.removeMessages(userId); 5073 5074 // If enough time passed, write without holding off anymore. 5075 final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis 5076 .get(userId); 5077 final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis 5078 - lastNotWrittenMutationTimeMillis; 5079 if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) { 5080 mHandler.obtainMessage(userId).sendToTarget(); 5081 return; 5082 } 5083 5084 // Hold off a bit more as settings are frequently changing. 5085 final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis 5086 + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0); 5087 final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS, 5088 maxDelayMillis); 5089 5090 Message message = mHandler.obtainMessage(userId); 5091 mHandler.sendMessageDelayed(message, writeDelayMillis); 5092 } else { 5093 mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis); 5094 Message message = mHandler.obtainMessage(userId); 5095 mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS); 5096 mWriteScheduled.put(userId, true); 5097 } 5098 } 5099 5100 private void writePermissionsSync(int userId) { 5101 AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId)); 5102 5103 ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>(); 5104 ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>(); 5105 5106 synchronized (mPersistenceLock) { 5107 mWriteScheduled.delete(userId); 5108 5109 final int packageCount = mPackages.size(); 5110 for (int i = 0; i < packageCount; i++) { 5111 String packageName = mPackages.keyAt(i); 5112 PackageSetting packageSetting = mPackages.valueAt(i); 5113 if (packageSetting.sharedUser == null) { 5114 PermissionsState permissionsState = packageSetting.getPermissionsState(); 5115 List<PermissionState> permissionsStates = permissionsState 5116 .getRuntimePermissionStates(userId); 5117 if (!permissionsStates.isEmpty()) { 5118 permissionsForPackage.put(packageName, permissionsStates); 5119 } 5120 } 5121 } 5122 5123 final int sharedUserCount = mSharedUsers.size(); 5124 for (int i = 0; i < sharedUserCount; i++) { 5125 String sharedUserName = mSharedUsers.keyAt(i); 5126 SharedUserSetting sharedUser = mSharedUsers.valueAt(i); 5127 PermissionsState permissionsState = sharedUser.getPermissionsState(); 5128 List<PermissionState> permissionsStates = permissionsState 5129 .getRuntimePermissionStates(userId); 5130 if (!permissionsStates.isEmpty()) { 5131 permissionsForSharedUser.put(sharedUserName, permissionsStates); 5132 } 5133 } 5134 } 5135 5136 FileOutputStream out = null; 5137 try { 5138 out = destination.startWrite(); 5139 5140 XmlSerializer serializer = Xml.newSerializer(); 5141 serializer.setOutput(out, StandardCharsets.UTF_8.name()); 5142 serializer.setFeature( 5143 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 5144 serializer.startDocument(null, true); 5145 5146 serializer.startTag(null, TAG_RUNTIME_PERMISSIONS); 5147 5148 String fingerprint = mFingerprints.get(userId); 5149 if (fingerprint != null) { 5150 serializer.attribute(null, ATTR_FINGERPRINT, fingerprint); 5151 } 5152 5153 final int packageCount = permissionsForPackage.size(); 5154 for (int i = 0; i < packageCount; i++) { 5155 String packageName = permissionsForPackage.keyAt(i); 5156 List<PermissionState> permissionStates = permissionsForPackage.valueAt(i); 5157 serializer.startTag(null, TAG_PACKAGE); 5158 serializer.attribute(null, ATTR_NAME, packageName); 5159 writePermissions(serializer, permissionStates); 5160 serializer.endTag(null, TAG_PACKAGE); 5161 } 5162 5163 final int sharedUserCount = permissionsForSharedUser.size(); 5164 for (int i = 0; i < sharedUserCount; i++) { 5165 String packageName = permissionsForSharedUser.keyAt(i); 5166 List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i); 5167 serializer.startTag(null, TAG_SHARED_USER); 5168 serializer.attribute(null, ATTR_NAME, packageName); 5169 writePermissions(serializer, permissionStates); 5170 serializer.endTag(null, TAG_SHARED_USER); 5171 } 5172 5173 serializer.endTag(null, TAG_RUNTIME_PERMISSIONS); 5174 5175 // Now any restored permission grants that are waiting for the apps 5176 // in question to be installed. These are stored as per-package 5177 // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some 5178 // number of individual permission grant entities. 5179 if (mRestoredUserGrants.get(userId) != null) { 5180 ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants = 5181 mRestoredUserGrants.get(userId); 5182 if (restoredGrants != null) { 5183 final int pkgCount = restoredGrants.size(); 5184 for (int i = 0; i < pkgCount; i++) { 5185 final ArraySet<RestoredPermissionGrant> pkgGrants = 5186 restoredGrants.valueAt(i); 5187 if (pkgGrants != null && pkgGrants.size() > 0) { 5188 final String pkgName = restoredGrants.keyAt(i); 5189 serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS); 5190 serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName); 5191 5192 final int N = pkgGrants.size(); 5193 for (int z = 0; z < N; z++) { 5194 RestoredPermissionGrant g = pkgGrants.valueAt(z); 5195 serializer.startTag(null, TAG_PERMISSION_ENTRY); 5196 serializer.attribute(null, ATTR_NAME, g.permissionName); 5197 5198 if (g.granted) { 5199 serializer.attribute(null, ATTR_GRANTED, "true"); 5200 } 5201 5202 if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) { 5203 serializer.attribute(null, ATTR_USER_SET, "true"); 5204 } 5205 if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) { 5206 serializer.attribute(null, ATTR_USER_FIXED, "true"); 5207 } 5208 if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) { 5209 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 5210 } 5211 serializer.endTag(null, TAG_PERMISSION_ENTRY); 5212 } 5213 serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS); 5214 } 5215 } 5216 } 5217 } 5218 5219 serializer.endDocument(); 5220 destination.finishWrite(out); 5221 5222 if (Build.FINGERPRINT.equals(fingerprint)) { 5223 mDefaultPermissionsGranted.put(userId, true); 5224 } 5225 // Any error while writing is fatal. 5226 } catch (Throwable t) { 5227 Slog.wtf(PackageManagerService.TAG, 5228 "Failed to write settings, restoring backup", t); 5229 destination.failWrite(out); 5230 } finally { 5231 IoUtils.closeQuietly(out); 5232 } 5233 } 5234 5235 private void onUserRemovedLPw(int userId) { 5236 // Make sure we do not 5237 mHandler.removeMessages(userId); 5238 5239 for (SettingBase sb : mPackages.values()) { 5240 revokeRuntimePermissionsAndClearFlags(sb, userId); 5241 } 5242 5243 for (SettingBase sb : mSharedUsers.values()) { 5244 revokeRuntimePermissionsAndClearFlags(sb, userId); 5245 } 5246 5247 mDefaultPermissionsGranted.delete(userId); 5248 mFingerprints.remove(userId); 5249 } 5250 5251 private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) { 5252 PermissionsState permissionsState = sb.getPermissionsState(); 5253 for (PermissionState permissionState 5254 : permissionsState.getRuntimePermissionStates(userId)) { 5255 BasePermission bp = mPermissions.getPermission(permissionState.getName()); 5256 if (bp != null) { 5257 permissionsState.revokeRuntimePermission(bp, userId); 5258 permissionsState.updatePermissionFlags(bp, userId, 5259 PackageManager.MASK_PERMISSION_FLAGS, 0); 5260 } 5261 } 5262 } 5263 5264 public void deleteUserRuntimePermissionsFile(int userId) { 5265 getUserRuntimePermissionsFile(userId).delete(); 5266 } 5267 5268 public void readStateForUserSyncLPr(int userId) { 5269 File permissionsFile = getUserRuntimePermissionsFile(userId); 5270 if (!permissionsFile.exists()) { 5271 return; 5272 } 5273 5274 FileInputStream in; 5275 try { 5276 in = new AtomicFile(permissionsFile).openRead(); 5277 } catch (FileNotFoundException fnfe) { 5278 Slog.i(PackageManagerService.TAG, "No permissions state"); 5279 return; 5280 } 5281 5282 try { 5283 XmlPullParser parser = Xml.newPullParser(); 5284 parser.setInput(in, null); 5285 parseRuntimePermissionsLPr(parser, userId); 5286 5287 } catch (XmlPullParserException | IOException e) { 5288 throw new IllegalStateException("Failed parsing permissions file: " 5289 + permissionsFile , e); 5290 } finally { 5291 IoUtils.closeQuietly(in); 5292 } 5293 } 5294 5295 // Backup/restore support 5296 5297 public void rememberRestoredUserGrantLPr(String pkgName, String permission, 5298 boolean isGranted, int restoredFlagSet, int userId) { 5299 // This change will be remembered at write-settings time 5300 ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage = 5301 mRestoredUserGrants.get(userId); 5302 if (grantsByPackage == null) { 5303 grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>(); 5304 mRestoredUserGrants.put(userId, grantsByPackage); 5305 } 5306 5307 ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName); 5308 if (grants == null) { 5309 grants = new ArraySet<RestoredPermissionGrant>(); 5310 grantsByPackage.put(pkgName, grants); 5311 } 5312 5313 RestoredPermissionGrant grant = new RestoredPermissionGrant(permission, 5314 isGranted, restoredFlagSet); 5315 grants.add(grant); 5316 } 5317 5318 // Private internals 5319 5320 private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId) 5321 throws IOException, XmlPullParserException { 5322 final int outerDepth = parser.getDepth(); 5323 int type; 5324 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 5325 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 5326 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 5327 continue; 5328 } 5329 5330 switch (parser.getName()) { 5331 case TAG_RUNTIME_PERMISSIONS: { 5332 String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT); 5333 mFingerprints.put(userId, fingerprint); 5334 final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint); 5335 mDefaultPermissionsGranted.put(userId, defaultsGranted); 5336 } break; 5337 5338 case TAG_PACKAGE: { 5339 String name = parser.getAttributeValue(null, ATTR_NAME); 5340 PackageSetting ps = mPackages.get(name); 5341 if (ps == null) { 5342 Slog.w(PackageManagerService.TAG, "Unknown package:" + name); 5343 XmlUtils.skipCurrentTag(parser); 5344 continue; 5345 } 5346 parsePermissionsLPr(parser, ps.getPermissionsState(), userId); 5347 } break; 5348 5349 case TAG_SHARED_USER: { 5350 String name = parser.getAttributeValue(null, ATTR_NAME); 5351 SharedUserSetting sus = mSharedUsers.get(name); 5352 if (sus == null) { 5353 Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name); 5354 XmlUtils.skipCurrentTag(parser); 5355 continue; 5356 } 5357 parsePermissionsLPr(parser, sus.getPermissionsState(), userId); 5358 } break; 5359 5360 case TAG_RESTORED_RUNTIME_PERMISSIONS: { 5361 final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 5362 parseRestoredRuntimePermissionsLPr(parser, pkgName, userId); 5363 } break; 5364 } 5365 } 5366 } 5367 5368 private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser, 5369 final String pkgName, final int userId) throws IOException, XmlPullParserException { 5370 final int outerDepth = parser.getDepth(); 5371 int type; 5372 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 5373 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 5374 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 5375 continue; 5376 } 5377 5378 switch (parser.getName()) { 5379 case TAG_PERMISSION_ENTRY: { 5380 final String permName = parser.getAttributeValue(null, ATTR_NAME); 5381 final boolean isGranted = "true".equals( 5382 parser.getAttributeValue(null, ATTR_GRANTED)); 5383 5384 int permBits = 0; 5385 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 5386 permBits |= FLAG_PERMISSION_USER_SET; 5387 } 5388 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 5389 permBits |= FLAG_PERMISSION_USER_FIXED; 5390 } 5391 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 5392 permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 5393 } 5394 5395 if (isGranted || permBits != 0) { 5396 rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId); 5397 } 5398 } break; 5399 } 5400 } 5401 } 5402 5403 private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState, 5404 int userId) throws IOException, XmlPullParserException { 5405 final int outerDepth = parser.getDepth(); 5406 int type; 5407 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 5408 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 5409 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 5410 continue; 5411 } 5412 5413 switch (parser.getName()) { 5414 case TAG_ITEM: { 5415 String name = parser.getAttributeValue(null, ATTR_NAME); 5416 BasePermission bp = mPermissions.getPermission(name); 5417 if (bp == null) { 5418 Slog.w(PackageManagerService.TAG, "Unknown permission:" + name); 5419 XmlUtils.skipCurrentTag(parser); 5420 continue; 5421 } 5422 5423 String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED); 5424 final boolean granted = grantedStr == null 5425 || Boolean.parseBoolean(grantedStr); 5426 5427 String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS); 5428 final int flags = (flagsStr != null) 5429 ? Integer.parseInt(flagsStr, 16) : 0; 5430 5431 if (granted) { 5432 permissionsState.grantRuntimePermission(bp, userId); 5433 permissionsState.updatePermissionFlags(bp, userId, 5434 PackageManager.MASK_PERMISSION_FLAGS, flags); 5435 } else { 5436 permissionsState.updatePermissionFlags(bp, userId, 5437 PackageManager.MASK_PERMISSION_FLAGS, flags); 5438 } 5439 5440 } break; 5441 } 5442 } 5443 } 5444 5445 private void writePermissions(XmlSerializer serializer, 5446 List<PermissionState> permissionStates) throws IOException { 5447 for (PermissionState permissionState : permissionStates) { 5448 serializer.startTag(null, TAG_ITEM); 5449 serializer.attribute(null, ATTR_NAME,permissionState.getName()); 5450 serializer.attribute(null, ATTR_GRANTED, 5451 String.valueOf(permissionState.isGranted())); 5452 serializer.attribute(null, ATTR_FLAGS, 5453 Integer.toHexString(permissionState.getFlags())); 5454 serializer.endTag(null, TAG_ITEM); 5455 } 5456 } 5457 5458 private final class MyHandler extends Handler { 5459 public MyHandler() { 5460 super(BackgroundThread.getHandler().getLooper()); 5461 } 5462 5463 @Override 5464 public void handleMessage(Message message) { 5465 final int userId = message.what; 5466 Runnable callback = (Runnable) message.obj; 5467 writePermissionsSync(userId); 5468 if (callback != null) { 5469 callback.run(); 5470 } 5471 } 5472 } 5473 } 5474} 5475