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