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