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