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