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