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