Settings.java revision 5455f6826f832ed0f07d28a772f4489d7223acb3
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_USER; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 23import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 24 25import com.android.internal.util.FastXmlSerializer; 26import com.android.internal.util.JournaledFile; 27import com.android.internal.util.XmlUtils; 28import com.android.server.IntentResolver; 29import com.android.server.pm.PackageManagerService.DumpState; 30 31import org.xmlpull.v1.XmlPullParser; 32import org.xmlpull.v1.XmlPullParserException; 33import org.xmlpull.v1.XmlSerializer; 34 35import android.content.ComponentName; 36import android.content.Context; 37import android.content.Intent; 38import android.content.pm.ApplicationInfo; 39import android.content.pm.ComponentInfo; 40import android.content.pm.PackageCleanItem; 41import android.content.pm.PackageManager; 42import android.content.pm.PackageParser; 43import android.content.pm.PermissionInfo; 44import android.content.pm.Signature; 45import android.content.pm.UserInfo; 46import android.content.pm.PackageUserState; 47import android.content.pm.VerifierDeviceIdentity; 48import android.os.Binder; 49import android.os.Environment; 50import android.os.FileUtils; 51import android.os.Process; 52import android.os.UserHandle; 53import android.util.Log; 54import android.util.Slog; 55import android.util.SparseArray; 56import android.util.Xml; 57 58import java.io.BufferedOutputStream; 59import java.io.File; 60import java.io.FileInputStream; 61import java.io.FileOutputStream; 62import java.io.IOException; 63import java.io.PrintWriter; 64import java.text.SimpleDateFormat; 65import java.util.ArrayList; 66import java.util.Arrays; 67import java.util.Date; 68import java.util.HashMap; 69import java.util.HashSet; 70import java.util.Iterator; 71import java.util.List; 72import java.util.Map; 73 74import libcore.io.IoUtils; 75 76/** 77 * Holds information about dynamic settings. 78 */ 79final class Settings { 80 private static final String TAG = "PackageSettings"; 81 82 private static final boolean DEBUG_STOPPED = false; 83 private static final boolean DEBUG_MU = false; 84 85 private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage"; 86 private static final String ATTR_ENFORCEMENT = "enforcement"; 87 88 private static final String TAG_ITEM = "item"; 89 private static final String TAG_DISABLED_COMPONENTS = "disabled-components"; 90 private static final String TAG_ENABLED_COMPONENTS = "enabled-components"; 91 private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions"; 92 private static final String TAG_PACKAGE = "pkg"; 93 94 private static final String ATTR_NAME = "name"; 95 private static final String ATTR_USER = "user"; 96 private static final String ATTR_CODE = "code"; 97 private static final String ATTR_NOT_LAUNCHED = "nl"; 98 private static final String ATTR_ENABLED = "enabled"; 99 private static final String ATTR_STOPPED = "stopped"; 100 private static final String ATTR_INSTALLED = "inst"; 101 102 private final File mSettingsFilename; 103 private final File mBackupSettingsFilename; 104 private final File mPackageListFilename; 105 private final File mStoppedPackagesFilename; 106 private final File mBackupStoppedPackagesFilename; 107 final HashMap<String, PackageSetting> mPackages = 108 new HashMap<String, PackageSetting>(); 109 // List of replaced system applications 110 private final HashMap<String, PackageSetting> mDisabledSysPackages = 111 new HashMap<String, PackageSetting>(); 112 113 // These are the last platform API version we were using for 114 // the apps installed on internal and external storage. It is 115 // used to grant newer permissions one time during a system upgrade. 116 int mInternalSdkPlatform; 117 int mExternalSdkPlatform; 118 119 Boolean mReadExternalStorageEnforced; 120 121 /** Device identity for the purpose of package verification. */ 122 private VerifierDeviceIdentity mVerifierDeviceIdentity; 123 124 // The user's preferred activities associated with particular intent 125 // filters. 126 final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities = 127 new IntentResolver<PreferredActivity, PreferredActivity>() { 128 @Override 129 protected PreferredActivity[] newArray(int size) { 130 return new PreferredActivity[size]; 131 } 132 @Override 133 protected String packageForFilter(PreferredActivity filter) { 134 return filter.mPref.mComponent.getPackageName(); 135 } 136 @Override 137 protected void dumpFilter(PrintWriter out, String prefix, 138 PreferredActivity filter) { 139 filter.mPref.dump(out, prefix, filter); 140 } 141 }; 142 final HashMap<String, SharedUserSetting> mSharedUsers = 143 new HashMap<String, SharedUserSetting>(); 144 private final ArrayList<Object> mUserIds = new ArrayList<Object>(); 145 private final SparseArray<Object> mOtherUserIds = 146 new SparseArray<Object>(); 147 148 // For reading/writing settings file. 149 private final ArrayList<Signature> mPastSignatures = 150 new ArrayList<Signature>(); 151 152 // Mapping from permission names to info about them. 153 final HashMap<String, BasePermission> mPermissions = 154 new HashMap<String, BasePermission>(); 155 156 // Mapping from permission tree names to info about them. 157 final HashMap<String, BasePermission> mPermissionTrees = 158 new HashMap<String, BasePermission>(); 159 160 // Packages that have been uninstalled and still need their external 161 // storage data deleted. 162 final SparseArray<ArrayList<PackageCleanItem>> mPackagesToBeCleaned 163 = new SparseArray<ArrayList<PackageCleanItem>>(); 164 165 // Packages that have been renamed since they were first installed. 166 // Keys are the new names of the packages, values are the original 167 // names. The packages appear everwhere else under their original 168 // names. 169 final HashMap<String, String> mRenamedPackages = new HashMap<String, String>(); 170 171 final StringBuilder mReadMessages = new StringBuilder(); 172 173 /** 174 * Used to track packages that have a shared user ID that hasn't been read 175 * in yet. 176 * <p> 177 * TODO: make this just a local variable that is passed in during package 178 * scanning to make it less confusing. 179 */ 180 private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>(); 181 182 private final Context mContext; 183 184 private final File mSystemDir; 185 Settings(Context context) { 186 this(context, Environment.getDataDirectory()); 187 } 188 189 Settings(Context context, File dataDir) { 190 mContext = context; 191 mSystemDir = new File(dataDir, "system"); 192 mSystemDir.mkdirs(); 193 FileUtils.setPermissions(mSystemDir.toString(), 194 FileUtils.S_IRWXU|FileUtils.S_IRWXG 195 |FileUtils.S_IROTH|FileUtils.S_IXOTH, 196 -1, -1); 197 mSettingsFilename = new File(mSystemDir, "packages.xml"); 198 mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); 199 mPackageListFilename = new File(mSystemDir, "packages.list"); 200 // Deprecated: Needed for migration 201 mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml"); 202 mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); 203 } 204 205 PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, 206 String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, 207 String nativeLibraryPathString, int pkgFlags, UserHandle user, boolean add) { 208 final String name = pkg.packageName; 209 PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath, 210 resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags, 211 user, add); 212 return p; 213 } 214 215 PackageSetting peekPackageLPr(String name) { 216 return mPackages.get(name); 217 } 218 219 void setInstallStatus(String pkgName, int status) { 220 PackageSetting p = mPackages.get(pkgName); 221 if(p != null) { 222 if(p.getInstallStatus() != status) { 223 p.setInstallStatus(status); 224 } 225 } 226 } 227 228 void setInstallerPackageName(String pkgName, 229 String installerPkgName) { 230 PackageSetting p = mPackages.get(pkgName); 231 if(p != null) { 232 p.setInstallerPackageName(installerPkgName); 233 } 234 } 235 236 SharedUserSetting getSharedUserLPw(String name, 237 int pkgFlags, boolean create) { 238 SharedUserSetting s = mSharedUsers.get(name); 239 if (s == null) { 240 if (!create) { 241 return null; 242 } 243 s = new SharedUserSetting(name, pkgFlags); 244 s.userId = newUserIdLPw(s); 245 Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId); 246 // < 0 means we couldn't assign a userid; fall out and return 247 // s, which is currently null 248 if (s.userId >= 0) { 249 mSharedUsers.put(name, s); 250 } 251 } 252 253 return s; 254 } 255 256 boolean disableSystemPackageLPw(String name) { 257 final PackageSetting p = mPackages.get(name); 258 if(p == null) { 259 Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package"); 260 return false; 261 } 262 final PackageSetting dp = mDisabledSysPackages.get(name); 263 // always make sure the system package code and resource paths dont change 264 if (dp == null) { 265 if((p.pkg != null) && (p.pkg.applicationInfo != null)) { 266 p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 267 } 268 mDisabledSysPackages.put(name, p); 269 270 // a little trick... when we install the new package, we don't 271 // want to modify the existing PackageSetting for the built-in 272 // version. so at this point we need a new PackageSetting that 273 // is okay to muck with. 274 PackageSetting newp = new PackageSetting(p); 275 replacePackageLPw(name, newp); 276 return true; 277 } 278 return false; 279 } 280 281 PackageSetting enableSystemPackageLPw(String name) { 282 PackageSetting p = mDisabledSysPackages.get(name); 283 if(p == null) { 284 Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled"); 285 return null; 286 } 287 // Reset flag in ApplicationInfo object 288 if((p.pkg != null) && (p.pkg.applicationInfo != null)) { 289 p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 290 } 291 PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath, 292 p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags); 293 mDisabledSysPackages.remove(name); 294 return ret; 295 } 296 297 boolean isDisabledSystemPackageLPr(String name) { 298 return mDisabledSysPackages.containsKey(name); 299 } 300 301 void removeDisabledSystemPackageLPw(String name) { 302 mDisabledSysPackages.remove(name); 303 } 304 305 PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath, 306 String nativeLibraryPathString, int uid, int vc, int pkgFlags) { 307 PackageSetting p = mPackages.get(name); 308 if (p != null) { 309 if (p.appId == uid) { 310 return p; 311 } 312 PackageManagerService.reportSettingsProblem(Log.ERROR, 313 "Adding duplicate package, keeping first: " + name); 314 return null; 315 } 316 p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString, 317 vc, pkgFlags); 318 p.appId = uid; 319 if (addUserIdLPw(uid, p, name)) { 320 mPackages.put(name, p); 321 return p; 322 } 323 return null; 324 } 325 326 SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) { 327 SharedUserSetting s = mSharedUsers.get(name); 328 if (s != null) { 329 if (s.userId == uid) { 330 return s; 331 } 332 PackageManagerService.reportSettingsProblem(Log.ERROR, 333 "Adding duplicate shared user, keeping first: " + name); 334 return null; 335 } 336 s = new SharedUserSetting(name, pkgFlags); 337 s.userId = uid; 338 if (addUserIdLPw(uid, s, name)) { 339 mSharedUsers.put(name, s); 340 return s; 341 } 342 return null; 343 } 344 345 // Transfer ownership of permissions from one package to another. 346 void transferPermissionsLPw(String origPkg, String newPkg) { 347 // Transfer ownership of permissions to the new package. 348 for (int i=0; i<2; i++) { 349 HashMap<String, BasePermission> permissions = 350 i == 0 ? mPermissionTrees : mPermissions; 351 for (BasePermission bp : permissions.values()) { 352 if (origPkg.equals(bp.sourcePackage)) { 353 if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, 354 "Moving permission " + bp.name 355 + " from pkg " + bp.sourcePackage 356 + " to " + newPkg); 357 bp.sourcePackage = newPkg; 358 bp.packageSetting = null; 359 bp.perm = null; 360 if (bp.pendingInfo != null) { 361 bp.pendingInfo.packageName = newPkg; 362 } 363 bp.uid = 0; 364 bp.gids = null; 365 } 366 } 367 } 368 } 369 370 private PackageSetting getPackageLPw(String name, PackageSetting origPackage, 371 String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, 372 String nativeLibraryPathString, int vc, int pkgFlags, 373 UserHandle installUser, boolean add) { 374 PackageSetting p = mPackages.get(name); 375 if (p != null) { 376 if (!p.codePath.equals(codePath)) { 377 // Check to see if its a disabled system app 378 if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 379 // This is an updated system app with versions in both system 380 // and data partition. Just let the most recent version 381 // take precedence. 382 Slog.w(PackageManagerService.TAG, "Trying to update system app code path from " 383 + p.codePathString + " to " + codePath.toString()); 384 } else { 385 // Just a change in the code path is not an issue, but 386 // let's log a message about it. 387 Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from " 388 + p.codePath + " to " + codePath + "; Retaining data and using new"); 389 /* 390 * Since we've changed paths, we need to prefer the new 391 * native library path over the one stored in the 392 * package settings since we might have moved from 393 * internal to external storage or vice versa. 394 */ 395 p.nativeLibraryPathString = nativeLibraryPathString; 396 } 397 } 398 if (p.sharedUser != sharedUser) { 399 PackageManagerService.reportSettingsProblem(Log.WARN, 400 "Package " + name + " shared user changed from " 401 + (p.sharedUser != null ? p.sharedUser.name : "<nothing>") 402 + " to " 403 + (sharedUser != null ? sharedUser.name : "<nothing>") 404 + "; replacing with new"); 405 p = null; 406 } else { 407 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) { 408 // If what we are scanning is a system package, then 409 // make it so, regardless of whether it was previously 410 // installed only in the data partition. 411 p.pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 412 } 413 } 414 } 415 if (p == null) { 416 if (origPackage != null) { 417 // We are consuming the data from an existing package. 418 p = new PackageSetting(origPackage.name, name, codePath, resourcePath, 419 nativeLibraryPathString, vc, pkgFlags); 420 if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " 421 + name + " is adopting original package " + origPackage.name); 422 // Note that we will retain the new package's signature so 423 // that we can keep its data. 424 PackageSignatures s = p.signatures; 425 p.copyFrom(origPackage); 426 p.signatures = s; 427 p.sharedUser = origPackage.sharedUser; 428 p.appId = origPackage.appId; 429 p.origPackage = origPackage; 430 mRenamedPackages.put(name, origPackage.name); 431 name = origPackage.name; 432 // Update new package state. 433 p.setTimeStamp(codePath.lastModified()); 434 } else { 435 p = new PackageSetting(name, realName, codePath, resourcePath, 436 nativeLibraryPathString, vc, pkgFlags); 437 p.setTimeStamp(codePath.lastModified()); 438 p.sharedUser = sharedUser; 439 // If this is not a system app, it starts out stopped. 440 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 441 if (DEBUG_STOPPED) { 442 RuntimeException e = new RuntimeException("here"); 443 e.fillInStackTrace(); 444 Slog.i(PackageManagerService.TAG, "Stopping package " + name, e); 445 } 446 List<UserInfo> users = getAllUsers(); 447 if (users != null) { 448 for (UserInfo user : users) { 449 // By default we consider this app to be installed 450 // for the user if no user has been specified (which 451 // means to leave it at its original value, and the 452 // original default value is true), or we are being 453 // asked to install for all users, or this is the 454 // user we are installing for. 455 final boolean installed = installUser == null 456 || installUser.getIdentifier() == UserHandle.USER_ALL 457 || installUser.getIdentifier() == user.id; 458 p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT, 459 installed, 460 true, // stopped, 461 true, // notLaunched 462 null, null); 463 writePackageRestrictionsLPr(user.id); 464 } 465 } 466 } 467 if (sharedUser != null) { 468 p.appId = sharedUser.userId; 469 } else { 470 // Clone the setting here for disabled system packages 471 PackageSetting dis = mDisabledSysPackages.get(name); 472 if (dis != null) { 473 // For disabled packages a new setting is created 474 // from the existing user id. This still has to be 475 // added to list of user id's 476 // Copy signatures from previous setting 477 if (dis.signatures.mSignatures != null) { 478 p.signatures.mSignatures = dis.signatures.mSignatures.clone(); 479 } 480 p.appId = dis.appId; 481 // Clone permissions 482 p.grantedPermissions = new HashSet<String>(dis.grantedPermissions); 483 // Clone component info 484 List<UserInfo> users = getAllUsers(); 485 if (users != null) { 486 for (UserInfo user : users) { 487 int userId = user.id; 488 p.setDisabledComponentsCopy( 489 dis.getDisabledComponents(userId), userId); 490 p.setEnabledComponentsCopy( 491 dis.getEnabledComponents(userId), userId); 492 } 493 } 494 // Add new setting to list of user ids 495 addUserIdLPw(p.appId, p, name); 496 } else { 497 // Assign new user id 498 p.appId = newUserIdLPw(p); 499 } 500 } 501 } 502 if (p.appId < 0) { 503 PackageManagerService.reportSettingsProblem(Log.WARN, 504 "Package " + name + " could not be assigned a valid uid"); 505 return null; 506 } 507 if (add) { 508 // Finish adding new package by adding it and updating shared 509 // user preferences 510 addPackageSettingLPw(p, name, sharedUser); 511 } 512 } else { 513 if (installUser != null) { 514 // The caller has explicitly specified the user they want this 515 // package installed for, and the package already exists. 516 // Make sure it conforms to the new request. 517 List<UserInfo> users = getAllUsers(); 518 if (users != null) { 519 for (UserInfo user : users) { 520 if (installUser.getIdentifier() == UserHandle.USER_ALL 521 || installUser.getIdentifier() == user.id) { 522 boolean installed = p.getInstalled(user.id); 523 if (!installed) { 524 p.setInstalled(true, user.id); 525 writePackageRestrictionsLPr(user.id); 526 } 527 } 528 } 529 } 530 } 531 } 532 return p; 533 } 534 535 void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) { 536 p.pkg = pkg; 537 // pkg.mSetEnabled = p.getEnabled(userId); 538 // pkg.mSetStopped = p.getStopped(userId); 539 final String codePath = pkg.applicationInfo.sourceDir; 540 final String resourcePath = pkg.applicationInfo.publicSourceDir; 541 // Update code path if needed 542 if (!codePath.equalsIgnoreCase(p.codePathString)) { 543 Slog.w(PackageManagerService.TAG, "Code path for pkg : " + p.pkg.packageName + 544 " changing from " + p.codePathString + " to " + codePath); 545 p.codePath = new File(codePath); 546 p.codePathString = codePath; 547 } 548 //Update resource path if needed 549 if (!resourcePath.equalsIgnoreCase(p.resourcePathString)) { 550 Slog.w(PackageManagerService.TAG, "Resource path for pkg : " + p.pkg.packageName + 551 " changing from " + p.resourcePathString + " to " + resourcePath); 552 p.resourcePath = new File(resourcePath); 553 p.resourcePathString = resourcePath; 554 } 555 // Update the native library path if needed 556 final String nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir; 557 if (nativeLibraryPath != null 558 && !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) { 559 p.nativeLibraryPathString = nativeLibraryPath; 560 } 561 // Update version code if needed 562 if (pkg.mVersionCode != p.versionCode) { 563 p.versionCode = pkg.mVersionCode; 564 } 565 // Update signatures if needed. 566 if (p.signatures.mSignatures == null) { 567 p.signatures.assignSignatures(pkg.mSignatures); 568 } 569 // Update flags if needed. 570 if (pkg.applicationInfo.flags != p.pkgFlags) { 571 p.pkgFlags = pkg.applicationInfo.flags; 572 } 573 // If this app defines a shared user id initialize 574 // the shared user signatures as well. 575 if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) { 576 p.sharedUser.signatures.assignSignatures(pkg.mSignatures); 577 } 578 addPackageSettingLPw(p, pkg.packageName, p.sharedUser); 579 } 580 581 // Utility method that adds a PackageSetting to mPackages and 582 // completes updating the shared user attributes 583 private void addPackageSettingLPw(PackageSetting p, String name, 584 SharedUserSetting sharedUser) { 585 mPackages.put(name, p); 586 if (sharedUser != null) { 587 if (p.sharedUser != null && p.sharedUser != sharedUser) { 588 PackageManagerService.reportSettingsProblem(Log.ERROR, 589 "Package " + p.name + " was user " 590 + p.sharedUser + " but is now " + sharedUser 591 + "; I am not changing its files so it will probably fail!"); 592 p.sharedUser.packages.remove(p); 593 } else if (p.appId != sharedUser.userId) { 594 PackageManagerService.reportSettingsProblem(Log.ERROR, 595 "Package " + p.name + " was user id " + p.appId 596 + " but is now user " + sharedUser 597 + " with id " + sharedUser.userId 598 + "; I am not changing its files so it will probably fail!"); 599 } 600 601 sharedUser.packages.add(p); 602 p.sharedUser = sharedUser; 603 p.appId = sharedUser.userId; 604 } 605 } 606 607 /* 608 * Update the shared user setting when a package using 609 * specifying the shared user id is removed. The gids 610 * associated with each permission of the deleted package 611 * are removed from the shared user's gid list only if its 612 * not in use by other permissions of packages in the 613 * shared user setting. 614 */ 615 void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) { 616 if ((deletedPs == null) || (deletedPs.pkg == null)) { 617 Slog.i(PackageManagerService.TAG, 618 "Trying to update info for null package. Just ignoring"); 619 return; 620 } 621 // No sharedUserId 622 if (deletedPs.sharedUser == null) { 623 return; 624 } 625 SharedUserSetting sus = deletedPs.sharedUser; 626 // Update permissions 627 for (String eachPerm : deletedPs.pkg.requestedPermissions) { 628 boolean used = false; 629 if (!sus.grantedPermissions.contains(eachPerm)) { 630 continue; 631 } 632 for (PackageSetting pkg:sus.packages) { 633 if (pkg.pkg != null && 634 !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) && 635 pkg.pkg.requestedPermissions.contains(eachPerm)) { 636 used = true; 637 break; 638 } 639 } 640 if (!used) { 641 // can safely delete this permission from list 642 sus.grantedPermissions.remove(eachPerm); 643 } 644 } 645 // Update gids 646 int newGids[] = globalGids; 647 for (String eachPerm : sus.grantedPermissions) { 648 BasePermission bp = mPermissions.get(eachPerm); 649 if (bp != null) { 650 newGids = PackageManagerService.appendInts(newGids, bp.gids); 651 } 652 } 653 sus.gids = newGids; 654 } 655 656 int removePackageLPw(String name) { 657 final PackageSetting p = mPackages.get(name); 658 if (p != null) { 659 mPackages.remove(name); 660 if (p.sharedUser != null) { 661 p.sharedUser.packages.remove(p); 662 if (p.sharedUser.packages.size() == 0) { 663 mSharedUsers.remove(p.sharedUser.name); 664 removeUserIdLPw(p.sharedUser.userId); 665 return p.sharedUser.userId; 666 } 667 } else { 668 removeUserIdLPw(p.appId); 669 return p.appId; 670 } 671 } 672 return -1; 673 } 674 675 private void replacePackageLPw(String name, PackageSetting newp) { 676 final PackageSetting p = mPackages.get(name); 677 if (p != null) { 678 if (p.sharedUser != null) { 679 p.sharedUser.packages.remove(p); 680 p.sharedUser.packages.add(newp); 681 } else { 682 replaceUserIdLPw(p.appId, newp); 683 } 684 } 685 mPackages.put(name, newp); 686 } 687 688 private boolean addUserIdLPw(int uid, Object obj, Object name) { 689 if (uid > Process.LAST_APPLICATION_UID) { 690 return false; 691 } 692 693 if (uid >= Process.FIRST_APPLICATION_UID) { 694 int N = mUserIds.size(); 695 final int index = uid - Process.FIRST_APPLICATION_UID; 696 while (index >= N) { 697 mUserIds.add(null); 698 N++; 699 } 700 if (mUserIds.get(index) != null) { 701 PackageManagerService.reportSettingsProblem(Log.ERROR, 702 "Adding duplicate user id: " + uid 703 + " name=" + name); 704 return false; 705 } 706 mUserIds.set(index, obj); 707 } else { 708 if (mOtherUserIds.get(uid) != null) { 709 PackageManagerService.reportSettingsProblem(Log.ERROR, 710 "Adding duplicate shared id: " + uid 711 + " name=" + name); 712 return false; 713 } 714 mOtherUserIds.put(uid, obj); 715 } 716 return true; 717 } 718 719 public Object getUserIdLPr(int uid) { 720 if (uid >= Process.FIRST_APPLICATION_UID) { 721 final int N = mUserIds.size(); 722 final int index = uid - Process.FIRST_APPLICATION_UID; 723 return index < N ? mUserIds.get(index) : null; 724 } else { 725 return mOtherUserIds.get(uid); 726 } 727 } 728 729 private void removeUserIdLPw(int uid) { 730 if (uid >= Process.FIRST_APPLICATION_UID) { 731 final int N = mUserIds.size(); 732 final int index = uid - Process.FIRST_APPLICATION_UID; 733 if (index < N) mUserIds.set(index, null); 734 } else { 735 mOtherUserIds.remove(uid); 736 } 737 } 738 739 private void replaceUserIdLPw(int uid, Object obj) { 740 if (uid >= Process.FIRST_APPLICATION_UID) { 741 final int N = mUserIds.size(); 742 final int index = uid - Process.FIRST_APPLICATION_UID; 743 if (index < N) mUserIds.set(index, obj); 744 } else { 745 mOtherUserIds.put(uid, obj); 746 } 747 } 748 749 private File getUserPackagesStateFile(int userId) { 750 return new File(Environment.getUserSystemDirectory(userId), "package-restrictions.xml"); 751 } 752 753 private File getUserPackagesStateBackupFile(int userId) { 754 return new File(Environment.getUserSystemDirectory(userId), 755 "package-restrictions-backup.xml"); 756 } 757 758 void writeAllUsersPackageRestrictionsLPr() { 759 List<UserInfo> users = getAllUsers(); 760 if (users == null) return; 761 762 for (UserInfo user : users) { 763 writePackageRestrictionsLPr(user.id); 764 } 765 } 766 767 void readAllUsersPackageRestrictionsLPr() { 768 List<UserInfo> users = getAllUsers(); 769 if (users == null) { 770 readPackageRestrictionsLPr(0); 771 return; 772 } 773 774 for (UserInfo user : users) { 775 readPackageRestrictionsLPr(user.id); 776 } 777 } 778 779 void readPackageRestrictionsLPr(int userId) { 780 if (DEBUG_MU) { 781 Log.i(TAG, "Reading package restrictions for user=" + userId); 782 } 783 FileInputStream str = null; 784 File userPackagesStateFile = getUserPackagesStateFile(userId); 785 File backupFile = getUserPackagesStateBackupFile(userId); 786 if (backupFile.exists()) { 787 try { 788 str = new FileInputStream(backupFile); 789 mReadMessages.append("Reading from backup stopped packages file\n"); 790 PackageManagerService.reportSettingsProblem(Log.INFO, 791 "Need to read from backup stopped packages file"); 792 if (userPackagesStateFile.exists()) { 793 // If both the backup and normal file exist, we 794 // ignore the normal one since it might have been 795 // corrupted. 796 Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file " 797 + userPackagesStateFile); 798 userPackagesStateFile.delete(); 799 } 800 } catch (java.io.IOException e) { 801 // We'll try for the normal settings file. 802 } 803 } 804 805 try { 806 if (str == null) { 807 if (!userPackagesStateFile.exists()) { 808 mReadMessages.append("No stopped packages file found\n"); 809 PackageManagerService.reportSettingsProblem(Log.INFO, 810 "No stopped packages file; " 811 + "assuming all started"); 812 // At first boot, make sure no packages are stopped. 813 // We usually want to have third party apps initialize 814 // in the stopped state, but not at first boot. Also 815 // consider all applications to be installed. 816 for (PackageSetting pkg : mPackages.values()) { 817 pkg.setUserState(userId, COMPONENT_ENABLED_STATE_DEFAULT, 818 true, // installed 819 false, // stopped 820 false, // notLaunched 821 null, null); 822 } 823 return; 824 } 825 str = new FileInputStream(userPackagesStateFile); 826 } 827 final XmlPullParser parser = Xml.newPullParser(); 828 parser.setInput(str, null); 829 830 int type; 831 while ((type=parser.next()) != XmlPullParser.START_TAG 832 && type != XmlPullParser.END_DOCUMENT) { 833 ; 834 } 835 836 if (type != XmlPullParser.START_TAG) { 837 mReadMessages.append("No start tag found in package restrictions file\n"); 838 PackageManagerService.reportSettingsProblem(Log.WARN, 839 "No start tag found in package manager stopped packages"); 840 return; 841 } 842 843 int outerDepth = parser.getDepth(); 844 PackageSetting ps = null; 845 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 846 && (type != XmlPullParser.END_TAG 847 || parser.getDepth() > outerDepth)) { 848 if (type == XmlPullParser.END_TAG 849 || type == XmlPullParser.TEXT) { 850 continue; 851 } 852 853 String tagName = parser.getName(); 854 if (tagName.equals(TAG_PACKAGE)) { 855 String name = parser.getAttributeValue(null, ATTR_NAME); 856 ps = mPackages.get(name); 857 if (ps == null) { 858 Slog.w(PackageManagerService.TAG, "No package known for stopped package: " 859 + name); 860 XmlUtils.skipCurrentTag(parser); 861 continue; 862 } 863 final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED); 864 final int enabled = enabledStr == null 865 ? COMPONENT_ENABLED_STATE_DEFAULT : Integer.parseInt(enabledStr); 866 final String installedStr = parser.getAttributeValue(null, ATTR_INSTALLED); 867 final boolean installed = installedStr == null 868 ? true : Boolean.parseBoolean(installedStr); 869 final String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED); 870 final boolean stopped = stoppedStr == null 871 ? false : Boolean.parseBoolean(stoppedStr); 872 final String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED); 873 final boolean notLaunched = stoppedStr == null 874 ? false : Boolean.parseBoolean(notLaunchedStr); 875 876 HashSet<String> enabledComponents = null; 877 HashSet<String> disabledComponents = null; 878 879 int packageDepth = parser.getDepth(); 880 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 881 && (type != XmlPullParser.END_TAG 882 || parser.getDepth() > packageDepth)) { 883 if (type == XmlPullParser.END_TAG 884 || type == XmlPullParser.TEXT) { 885 continue; 886 } 887 tagName = parser.getName(); 888 if (tagName.equals(TAG_ENABLED_COMPONENTS)) { 889 enabledComponents = readComponentsLPr(parser); 890 } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) { 891 disabledComponents = readComponentsLPr(parser); 892 } 893 } 894 895 ps.setUserState(userId, enabled, installed, stopped, notLaunched, 896 enabledComponents, disabledComponents); 897 } else { 898 Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " 899 + parser.getName()); 900 XmlUtils.skipCurrentTag(parser); 901 } 902 } 903 904 str.close(); 905 906 } catch (XmlPullParserException e) { 907 mReadMessages.append("Error reading: " + e.toString()); 908 PackageManagerService.reportSettingsProblem(Log.ERROR, 909 "Error reading stopped packages: " + e); 910 Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); 911 912 } catch (java.io.IOException e) { 913 mReadMessages.append("Error reading: " + e.toString()); 914 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 915 Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); 916 } 917 } 918 919 private HashSet<String> readComponentsLPr(XmlPullParser parser) 920 throws IOException, XmlPullParserException { 921 HashSet<String> components = null; 922 int type; 923 int outerDepth = parser.getDepth(); 924 String tagName; 925 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 926 && (type != XmlPullParser.END_TAG 927 || parser.getDepth() > outerDepth)) { 928 if (type == XmlPullParser.END_TAG 929 || type == XmlPullParser.TEXT) { 930 continue; 931 } 932 tagName = parser.getName(); 933 if (tagName.equals(TAG_ITEM)) { 934 String componentName = parser.getAttributeValue(null, ATTR_NAME); 935 if (componentName != null) { 936 if (components == null) { 937 components = new HashSet<String>(); 938 } 939 components.add(componentName); 940 } 941 } 942 } 943 return components; 944 } 945 946 void writePackageRestrictionsLPr(int userId) { 947 if (DEBUG_MU) { 948 Log.i(TAG, "Writing package restrictions for user=" + userId); 949 } 950 // Keep the old stopped packages around until we know the new ones have 951 // been successfully written. 952 File userPackagesStateFile = getUserPackagesStateFile(userId); 953 File backupFile = getUserPackagesStateBackupFile(userId); 954 new File(userPackagesStateFile.getParent()).mkdirs(); 955 if (userPackagesStateFile.exists()) { 956 // Presence of backup settings file indicates that we failed 957 // to persist packages earlier. So preserve the older 958 // backup for future reference since the current packages 959 // might have been corrupted. 960 if (!backupFile.exists()) { 961 if (!userPackagesStateFile.renameTo(backupFile)) { 962 Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, " 963 + "current changes will be lost at reboot"); 964 return; 965 } 966 } else { 967 userPackagesStateFile.delete(); 968 Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup"); 969 } 970 } 971 972 try { 973 final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile); 974 final BufferedOutputStream str = new BufferedOutputStream(fstr); 975 976 final XmlSerializer serializer = new FastXmlSerializer(); 977 serializer.setOutput(str, "utf-8"); 978 serializer.startDocument(null, true); 979 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 980 981 serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS); 982 983 for (final PackageSetting pkg : mPackages.values()) { 984 PackageUserState ustate = pkg.readUserState(userId); 985 if (ustate.stopped || ustate.notLaunched || !ustate.installed 986 || ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT 987 || (ustate.enabledComponents != null 988 && ustate.enabledComponents.size() > 0) 989 || (ustate.disabledComponents != null 990 && ustate.disabledComponents.size() > 0)) { 991 serializer.startTag(null, TAG_PACKAGE); 992 serializer.attribute(null, ATTR_NAME, pkg.name); 993 if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled); 994 995 if (!ustate.installed) { 996 serializer.attribute(null, ATTR_INSTALLED, "false"); 997 } 998 if (ustate.stopped) { 999 serializer.attribute(null, ATTR_STOPPED, "true"); 1000 } 1001 if (ustate.notLaunched) { 1002 serializer.attribute(null, ATTR_NOT_LAUNCHED, "true"); 1003 } 1004 if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) { 1005 serializer.attribute(null, ATTR_ENABLED, 1006 Integer.toString(ustate.enabled)); 1007 } 1008 if (ustate.enabledComponents != null 1009 && ustate.enabledComponents.size() > 0) { 1010 serializer.startTag(null, TAG_ENABLED_COMPONENTS); 1011 for (final String name : ustate.enabledComponents) { 1012 serializer.startTag(null, TAG_ITEM); 1013 serializer.attribute(null, ATTR_NAME, name); 1014 serializer.endTag(null, TAG_ITEM); 1015 } 1016 serializer.endTag(null, TAG_ENABLED_COMPONENTS); 1017 } 1018 if (ustate.disabledComponents != null 1019 && ustate.disabledComponents.size() > 0) { 1020 serializer.startTag(null, TAG_DISABLED_COMPONENTS); 1021 for (final String name : ustate.disabledComponents) { 1022 serializer.startTag(null, TAG_ITEM); 1023 serializer.attribute(null, ATTR_NAME, name); 1024 serializer.endTag(null, TAG_ITEM); 1025 } 1026 serializer.endTag(null, TAG_DISABLED_COMPONENTS); 1027 } 1028 serializer.endTag(null, TAG_PACKAGE); 1029 } 1030 } 1031 1032 serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); 1033 1034 serializer.endDocument(); 1035 1036 str.flush(); 1037 FileUtils.sync(fstr); 1038 str.close(); 1039 1040 // New settings successfully written, old ones are no longer 1041 // needed. 1042 backupFile.delete(); 1043 FileUtils.setPermissions(userPackagesStateFile.toString(), 1044 FileUtils.S_IRUSR|FileUtils.S_IWUSR 1045 |FileUtils.S_IRGRP|FileUtils.S_IWGRP, 1046 -1, -1); 1047 1048 // Done, all is good! 1049 return; 1050 } catch(java.io.IOException e) { 1051 Log.wtf(PackageManagerService.TAG, 1052 "Unable to write package manager user packages state, " 1053 + " current changes will be lost at reboot", e); 1054 } 1055 1056 // Clean up partially written files 1057 if (userPackagesStateFile.exists()) { 1058 if (!userPackagesStateFile.delete()) { 1059 Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: " 1060 + mStoppedPackagesFilename); 1061 } 1062 } 1063 } 1064 1065 // Note: assumed "stopped" field is already cleared in all packages. 1066 // Legacy reader, used to read in the old file format after an upgrade. Not used after that. 1067 void readStoppedLPw() { 1068 FileInputStream str = null; 1069 if (mBackupStoppedPackagesFilename.exists()) { 1070 try { 1071 str = new FileInputStream(mBackupStoppedPackagesFilename); 1072 mReadMessages.append("Reading from backup stopped packages file\n"); 1073 PackageManagerService.reportSettingsProblem(Log.INFO, 1074 "Need to read from backup stopped packages file"); 1075 if (mSettingsFilename.exists()) { 1076 // If both the backup and normal file exist, we 1077 // ignore the normal one since it might have been 1078 // corrupted. 1079 Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file " 1080 + mStoppedPackagesFilename); 1081 mStoppedPackagesFilename.delete(); 1082 } 1083 } catch (java.io.IOException e) { 1084 // We'll try for the normal settings file. 1085 } 1086 } 1087 1088 try { 1089 if (str == null) { 1090 if (!mStoppedPackagesFilename.exists()) { 1091 mReadMessages.append("No stopped packages file found\n"); 1092 PackageManagerService.reportSettingsProblem(Log.INFO, 1093 "No stopped packages file file; assuming all started"); 1094 // At first boot, make sure no packages are stopped. 1095 // We usually want to have third party apps initialize 1096 // in the stopped state, but not at first boot. 1097 for (PackageSetting pkg : mPackages.values()) { 1098 pkg.setStopped(false, 0); 1099 pkg.setNotLaunched(false, 0); 1100 } 1101 return; 1102 } 1103 str = new FileInputStream(mStoppedPackagesFilename); 1104 } 1105 final XmlPullParser parser = Xml.newPullParser(); 1106 parser.setInput(str, null); 1107 1108 int type; 1109 while ((type=parser.next()) != XmlPullParser.START_TAG 1110 && type != XmlPullParser.END_DOCUMENT) { 1111 ; 1112 } 1113 1114 if (type != XmlPullParser.START_TAG) { 1115 mReadMessages.append("No start tag found in stopped packages file\n"); 1116 PackageManagerService.reportSettingsProblem(Log.WARN, 1117 "No start tag found in package manager stopped packages"); 1118 return; 1119 } 1120 1121 int outerDepth = parser.getDepth(); 1122 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1123 && (type != XmlPullParser.END_TAG 1124 || parser.getDepth() > outerDepth)) { 1125 if (type == XmlPullParser.END_TAG 1126 || type == XmlPullParser.TEXT) { 1127 continue; 1128 } 1129 1130 String tagName = parser.getName(); 1131 if (tagName.equals(TAG_PACKAGE)) { 1132 String name = parser.getAttributeValue(null, ATTR_NAME); 1133 PackageSetting ps = mPackages.get(name); 1134 if (ps != null) { 1135 ps.setStopped(true, 0); 1136 if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) { 1137 ps.setNotLaunched(true, 0); 1138 } 1139 } else { 1140 Slog.w(PackageManagerService.TAG, 1141 "No package known for stopped package: " + name); 1142 } 1143 XmlUtils.skipCurrentTag(parser); 1144 } else { 1145 Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " 1146 + parser.getName()); 1147 XmlUtils.skipCurrentTag(parser); 1148 } 1149 } 1150 1151 str.close(); 1152 1153 } catch (XmlPullParserException e) { 1154 mReadMessages.append("Error reading: " + e.toString()); 1155 PackageManagerService.reportSettingsProblem(Log.ERROR, 1156 "Error reading stopped packages: " + e); 1157 Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); 1158 1159 } catch (java.io.IOException e) { 1160 mReadMessages.append("Error reading: " + e.toString()); 1161 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 1162 Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); 1163 1164 } 1165 } 1166 1167 void writeLPr() { 1168 //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024); 1169 1170 // Keep the old settings around until we know the new ones have 1171 // been successfully written. 1172 if (mSettingsFilename.exists()) { 1173 // Presence of backup settings file indicates that we failed 1174 // to persist settings earlier. So preserve the older 1175 // backup for future reference since the current settings 1176 // might have been corrupted. 1177 if (!mBackupSettingsFilename.exists()) { 1178 if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) { 1179 Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, " 1180 + " current changes will be lost at reboot"); 1181 return; 1182 } 1183 } else { 1184 mSettingsFilename.delete(); 1185 Slog.w(PackageManagerService.TAG, "Preserving older settings backup"); 1186 } 1187 } 1188 1189 mPastSignatures.clear(); 1190 1191 try { 1192 FileOutputStream fstr = new FileOutputStream(mSettingsFilename); 1193 BufferedOutputStream str = new BufferedOutputStream(fstr); 1194 1195 //XmlSerializer serializer = XmlUtils.serializerInstance(); 1196 XmlSerializer serializer = new FastXmlSerializer(); 1197 serializer.setOutput(str, "utf-8"); 1198 serializer.startDocument(null, true); 1199 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 1200 1201 serializer.startTag(null, "packages"); 1202 1203 serializer.startTag(null, "last-platform-version"); 1204 serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform)); 1205 serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform)); 1206 serializer.endTag(null, "last-platform-version"); 1207 1208 if (mVerifierDeviceIdentity != null) { 1209 serializer.startTag(null, "verifier"); 1210 serializer.attribute(null, "device", mVerifierDeviceIdentity.toString()); 1211 serializer.endTag(null, "verifier"); 1212 } 1213 1214 if (mReadExternalStorageEnforced != null) { 1215 serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE); 1216 serializer.attribute( 1217 null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0"); 1218 serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE); 1219 } 1220 1221 serializer.startTag(null, "permission-trees"); 1222 for (BasePermission bp : mPermissionTrees.values()) { 1223 writePermissionLPr(serializer, bp); 1224 } 1225 serializer.endTag(null, "permission-trees"); 1226 1227 serializer.startTag(null, "permissions"); 1228 for (BasePermission bp : mPermissions.values()) { 1229 writePermissionLPr(serializer, bp); 1230 } 1231 serializer.endTag(null, "permissions"); 1232 1233 for (final PackageSetting pkg : mPackages.values()) { 1234 writePackageLPr(serializer, pkg); 1235 } 1236 1237 for (final PackageSetting pkg : mDisabledSysPackages.values()) { 1238 writeDisabledSysPackageLPr(serializer, pkg); 1239 } 1240 1241 writePreferredActivitiesLPr(serializer); 1242 1243 for (final SharedUserSetting usr : mSharedUsers.values()) { 1244 serializer.startTag(null, "shared-user"); 1245 serializer.attribute(null, ATTR_NAME, usr.name); 1246 serializer.attribute(null, "userId", 1247 Integer.toString(usr.userId)); 1248 usr.signatures.writeXml(serializer, "sigs", mPastSignatures); 1249 serializer.startTag(null, "perms"); 1250 for (String name : usr.grantedPermissions) { 1251 serializer.startTag(null, TAG_ITEM); 1252 serializer.attribute(null, ATTR_NAME, name); 1253 serializer.endTag(null, TAG_ITEM); 1254 } 1255 serializer.endTag(null, "perms"); 1256 serializer.endTag(null, "shared-user"); 1257 } 1258 1259 if (mPackagesToBeCleaned.size() > 0) { 1260 for (int i=0; i<mPackagesToBeCleaned.size(); i++) { 1261 final int userId = mPackagesToBeCleaned.keyAt(i); 1262 final String userStr = Integer.toString(userId); 1263 final ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.valueAt(i); 1264 for (int j=0; j<pkgs.size(); j++) { 1265 serializer.startTag(null, "cleaning-package"); 1266 PackageCleanItem item = pkgs.get(j); 1267 serializer.attribute(null, ATTR_NAME, item.packageName); 1268 serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false"); 1269 serializer.attribute(null, ATTR_USER, userStr); 1270 serializer.endTag(null, "cleaning-package"); 1271 } 1272 } 1273 } 1274 1275 if (mRenamedPackages.size() > 0) { 1276 for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) { 1277 serializer.startTag(null, "renamed-package"); 1278 serializer.attribute(null, "new", e.getKey()); 1279 serializer.attribute(null, "old", e.getValue()); 1280 serializer.endTag(null, "renamed-package"); 1281 } 1282 } 1283 1284 serializer.endTag(null, "packages"); 1285 1286 serializer.endDocument(); 1287 1288 str.flush(); 1289 FileUtils.sync(fstr); 1290 str.close(); 1291 1292 // New settings successfully written, old ones are no longer 1293 // needed. 1294 mBackupSettingsFilename.delete(); 1295 FileUtils.setPermissions(mSettingsFilename.toString(), 1296 FileUtils.S_IRUSR|FileUtils.S_IWUSR 1297 |FileUtils.S_IRGRP|FileUtils.S_IWGRP, 1298 -1, -1); 1299 1300 // Write package list file now, use a JournaledFile. 1301 // 1302 File tempFile = new File(mPackageListFilename.toString() + ".tmp"); 1303 JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile); 1304 1305 fstr = new FileOutputStream(journal.chooseForWrite()); 1306 str = new BufferedOutputStream(fstr); 1307 try { 1308 StringBuilder sb = new StringBuilder(); 1309 for (final PackageSetting pkg : mPackages.values()) { 1310 ApplicationInfo ai = pkg.pkg.applicationInfo; 1311 String dataPath = ai.dataDir; 1312 boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 1313 1314 // Avoid any application that has a space in its path 1315 // or that is handled by the system. 1316 if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID) 1317 continue; 1318 1319 // we store on each line the following information for now: 1320 // 1321 // pkgName - package name 1322 // userId - application-specific user id 1323 // debugFlag - 0 or 1 if the package is debuggable. 1324 // dataPath - path to package's data path 1325 // 1326 // NOTE: We prefer not to expose all ApplicationInfo flags for now. 1327 // 1328 // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS 1329 // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES: 1330 // system/core/run-as/run-as.c 1331 // 1332 sb.setLength(0); 1333 sb.append(ai.packageName); 1334 sb.append(" "); 1335 sb.append((int)ai.uid); 1336 sb.append(isDebug ? " 1 " : " 0 "); 1337 sb.append(dataPath); 1338 sb.append("\n"); 1339 str.write(sb.toString().getBytes()); 1340 } 1341 str.flush(); 1342 FileUtils.sync(fstr); 1343 str.close(); 1344 journal.commit(); 1345 } catch (Exception e) { 1346 IoUtils.closeQuietly(str); 1347 journal.rollback(); 1348 } 1349 1350 FileUtils.setPermissions(mPackageListFilename.toString(), 1351 FileUtils.S_IRUSR|FileUtils.S_IWUSR 1352 |FileUtils.S_IRGRP|FileUtils.S_IWGRP, 1353 -1, -1); 1354 1355 writeAllUsersPackageRestrictionsLPr(); 1356 return; 1357 1358 } catch(XmlPullParserException e) { 1359 Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " 1360 + "current changes will be lost at reboot", e); 1361 } catch(java.io.IOException e) { 1362 Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " 1363 + "current changes will be lost at reboot", e); 1364 } 1365 // Clean up partially written files 1366 if (mSettingsFilename.exists()) { 1367 if (!mSettingsFilename.delete()) { 1368 Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " 1369 + mSettingsFilename); 1370 } 1371 } 1372 //Debug.stopMethodTracing(); 1373 } 1374 1375 void writePreferredActivitiesLPr(XmlSerializer serializer) 1376 throws IllegalArgumentException, IllegalStateException, IOException { 1377 serializer.startTag(null, "preferred-activities"); 1378 for (final PreferredActivity pa : mPreferredActivities.filterSet()) { 1379 serializer.startTag(null, TAG_ITEM); 1380 pa.writeToXml(serializer); 1381 serializer.endTag(null, TAG_ITEM); 1382 } 1383 serializer.endTag(null, "preferred-activities"); 1384 } 1385 1386 void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg) 1387 throws java.io.IOException { 1388 serializer.startTag(null, "updated-package"); 1389 serializer.attribute(null, ATTR_NAME, pkg.name); 1390 if (pkg.realName != null) { 1391 serializer.attribute(null, "realName", pkg.realName); 1392 } 1393 serializer.attribute(null, "codePath", pkg.codePathString); 1394 serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); 1395 serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime)); 1396 serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); 1397 serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); 1398 if (!pkg.resourcePathString.equals(pkg.codePathString)) { 1399 serializer.attribute(null, "resourcePath", pkg.resourcePathString); 1400 } 1401 if (pkg.nativeLibraryPathString != null) { 1402 serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString); 1403 } 1404 if (pkg.sharedUser == null) { 1405 serializer.attribute(null, "userId", Integer.toString(pkg.appId)); 1406 } else { 1407 serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId)); 1408 } 1409 serializer.startTag(null, "perms"); 1410 if (pkg.sharedUser == null) { 1411 // If this is a shared user, the permissions will 1412 // be written there. We still need to write an 1413 // empty permissions list so permissionsFixed will 1414 // be set. 1415 for (final String name : pkg.grantedPermissions) { 1416 BasePermission bp = mPermissions.get(name); 1417 if (bp != null) { 1418 // We only need to write signature or system permissions but 1419 // this wont 1420 // match the semantics of grantedPermissions. So write all 1421 // permissions. 1422 serializer.startTag(null, TAG_ITEM); 1423 serializer.attribute(null, ATTR_NAME, name); 1424 serializer.endTag(null, TAG_ITEM); 1425 } 1426 } 1427 } 1428 serializer.endTag(null, "perms"); 1429 serializer.endTag(null, "updated-package"); 1430 } 1431 1432 void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg) 1433 throws java.io.IOException { 1434 serializer.startTag(null, "package"); 1435 serializer.attribute(null, ATTR_NAME, pkg.name); 1436 if (pkg.realName != null) { 1437 serializer.attribute(null, "realName", pkg.realName); 1438 } 1439 serializer.attribute(null, "codePath", pkg.codePathString); 1440 if (!pkg.resourcePathString.equals(pkg.codePathString)) { 1441 serializer.attribute(null, "resourcePath", pkg.resourcePathString); 1442 } 1443 if (pkg.nativeLibraryPathString != null) { 1444 serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString); 1445 } 1446 serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags)); 1447 serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); 1448 serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime)); 1449 serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); 1450 serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); 1451 if (pkg.sharedUser == null) { 1452 serializer.attribute(null, "userId", Integer.toString(pkg.appId)); 1453 } else { 1454 serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId)); 1455 } 1456 if (pkg.uidError) { 1457 serializer.attribute(null, "uidError", "true"); 1458 } 1459 if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) { 1460 serializer.attribute(null, "installStatus", "false"); 1461 } 1462 if (pkg.installerPackageName != null) { 1463 serializer.attribute(null, "installer", pkg.installerPackageName); 1464 } 1465 pkg.signatures.writeXml(serializer, "sigs", mPastSignatures); 1466 if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1467 serializer.startTag(null, "perms"); 1468 if (pkg.sharedUser == null) { 1469 // If this is a shared user, the permissions will 1470 // be written there. We still need to write an 1471 // empty permissions list so permissionsFixed will 1472 // be set. 1473 for (final String name : pkg.grantedPermissions) { 1474 serializer.startTag(null, TAG_ITEM); 1475 serializer.attribute(null, ATTR_NAME, name); 1476 serializer.endTag(null, TAG_ITEM); 1477 } 1478 } 1479 serializer.endTag(null, "perms"); 1480 } 1481 1482 serializer.endTag(null, "package"); 1483 } 1484 1485 void writePermissionLPr(XmlSerializer serializer, BasePermission bp) 1486 throws XmlPullParserException, java.io.IOException { 1487 if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) { 1488 serializer.startTag(null, TAG_ITEM); 1489 serializer.attribute(null, ATTR_NAME, bp.name); 1490 serializer.attribute(null, "package", bp.sourcePackage); 1491 if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) { 1492 serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel)); 1493 } 1494 if (PackageManagerService.DEBUG_SETTINGS) 1495 Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type=" 1496 + bp.type); 1497 if (bp.type == BasePermission.TYPE_DYNAMIC) { 1498 final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo; 1499 if (pi != null) { 1500 serializer.attribute(null, "type", "dynamic"); 1501 if (pi.icon != 0) { 1502 serializer.attribute(null, "icon", Integer.toString(pi.icon)); 1503 } 1504 if (pi.nonLocalizedLabel != null) { 1505 serializer.attribute(null, "label", pi.nonLocalizedLabel.toString()); 1506 } 1507 } 1508 } 1509 serializer.endTag(null, TAG_ITEM); 1510 } 1511 } 1512 1513 ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() { 1514 final HashSet<String> kList = new HashSet<String>(mPackages.keySet()); 1515 final Iterator<String> its = kList.iterator(); 1516 final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>(); 1517 while (its.hasNext()) { 1518 final String key = its.next(); 1519 final PackageSetting ps = mPackages.get(key); 1520 if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) { 1521 ret.add(ps); 1522 } 1523 } 1524 return ret; 1525 } 1526 1527 void addPackageToCleanLPw(int userId, PackageCleanItem pkg) { 1528 ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.get(userId); 1529 if (pkgs == null) { 1530 pkgs = new ArrayList<PackageCleanItem>(); 1531 mPackagesToBeCleaned.put(userId, pkgs); 1532 } 1533 if (!pkgs.contains(pkg)) { 1534 pkgs.add(pkg); 1535 } 1536 } 1537 1538 boolean readLPw(List<UserInfo> users) { 1539 FileInputStream str = null; 1540 if (mBackupSettingsFilename.exists()) { 1541 try { 1542 str = new FileInputStream(mBackupSettingsFilename); 1543 mReadMessages.append("Reading from backup settings file\n"); 1544 PackageManagerService.reportSettingsProblem(Log.INFO, 1545 "Need to read from backup settings file"); 1546 if (mSettingsFilename.exists()) { 1547 // If both the backup and settings file exist, we 1548 // ignore the settings since it might have been 1549 // corrupted. 1550 Slog.w(PackageManagerService.TAG, "Cleaning up settings file " 1551 + mSettingsFilename); 1552 mSettingsFilename.delete(); 1553 } 1554 } catch (java.io.IOException e) { 1555 // We'll try for the normal settings file. 1556 } 1557 } 1558 1559 mPendingPackages.clear(); 1560 mPastSignatures.clear(); 1561 1562 try { 1563 if (str == null) { 1564 if (!mSettingsFilename.exists()) { 1565 mReadMessages.append("No settings file found\n"); 1566 PackageManagerService.reportSettingsProblem(Log.INFO, 1567 "No settings file; creating initial state"); 1568 readDefaultPreferredAppsLPw(); 1569 return false; 1570 } 1571 str = new FileInputStream(mSettingsFilename); 1572 } 1573 XmlPullParser parser = Xml.newPullParser(); 1574 parser.setInput(str, null); 1575 1576 int type; 1577 while ((type = parser.next()) != XmlPullParser.START_TAG 1578 && type != XmlPullParser.END_DOCUMENT) { 1579 ; 1580 } 1581 1582 if (type != XmlPullParser.START_TAG) { 1583 mReadMessages.append("No start tag found in settings file\n"); 1584 PackageManagerService.reportSettingsProblem(Log.WARN, 1585 "No start tag found in package manager settings"); 1586 Log.wtf(PackageManagerService.TAG, 1587 "No start tag found in package manager settings"); 1588 return false; 1589 } 1590 1591 int outerDepth = parser.getDepth(); 1592 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1593 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1594 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1595 continue; 1596 } 1597 1598 String tagName = parser.getName(); 1599 if (tagName.equals("package")) { 1600 readPackageLPw(parser); 1601 } else if (tagName.equals("permissions")) { 1602 readPermissionsLPw(mPermissions, parser); 1603 } else if (tagName.equals("permission-trees")) { 1604 readPermissionsLPw(mPermissionTrees, parser); 1605 } else if (tagName.equals("shared-user")) { 1606 readSharedUserLPw(parser); 1607 } else if (tagName.equals("preferred-packages")) { 1608 // no longer used. 1609 } else if (tagName.equals("preferred-activities")) { 1610 readPreferredActivitiesLPw(parser); 1611 } else if (tagName.equals("updated-package")) { 1612 readDisabledSysPackageLPw(parser); 1613 } else if (tagName.equals("cleaning-package")) { 1614 String name = parser.getAttributeValue(null, ATTR_NAME); 1615 String userStr = parser.getAttributeValue(null, ATTR_USER); 1616 String codeStr = parser.getAttributeValue(null, ATTR_CODE); 1617 if (name != null) { 1618 int user = 0; 1619 boolean andCode = true; 1620 try { 1621 if (userStr != null) { 1622 user = Integer.parseInt(userStr); 1623 } 1624 } catch (NumberFormatException e) { 1625 } 1626 if (codeStr != null) { 1627 andCode = Boolean.parseBoolean(codeStr); 1628 } 1629 addPackageToCleanLPw(user, new PackageCleanItem(name, andCode)); 1630 } 1631 } else if (tagName.equals("renamed-package")) { 1632 String nname = parser.getAttributeValue(null, "new"); 1633 String oname = parser.getAttributeValue(null, "old"); 1634 if (nname != null && oname != null) { 1635 mRenamedPackages.put(nname, oname); 1636 } 1637 } else if (tagName.equals("last-platform-version")) { 1638 mInternalSdkPlatform = mExternalSdkPlatform = 0; 1639 try { 1640 String internal = parser.getAttributeValue(null, "internal"); 1641 if (internal != null) { 1642 mInternalSdkPlatform = Integer.parseInt(internal); 1643 } 1644 String external = parser.getAttributeValue(null, "external"); 1645 if (external != null) { 1646 mExternalSdkPlatform = Integer.parseInt(external); 1647 } 1648 } catch (NumberFormatException e) { 1649 } 1650 } else if (tagName.equals("verifier")) { 1651 final String deviceIdentity = parser.getAttributeValue(null, "device"); 1652 try { 1653 mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity); 1654 } catch (IllegalArgumentException e) { 1655 Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: " 1656 + e.getMessage()); 1657 } 1658 } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) { 1659 final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT); 1660 mReadExternalStorageEnforced = "1".equals(enforcement); 1661 } else { 1662 Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: " 1663 + parser.getName()); 1664 XmlUtils.skipCurrentTag(parser); 1665 } 1666 } 1667 1668 str.close(); 1669 1670 } catch (XmlPullParserException e) { 1671 mReadMessages.append("Error reading: " + e.toString()); 1672 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 1673 Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); 1674 1675 } catch (java.io.IOException e) { 1676 mReadMessages.append("Error reading: " + e.toString()); 1677 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 1678 Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); 1679 } 1680 1681 if (mBackupStoppedPackagesFilename.exists() 1682 || mStoppedPackagesFilename.exists()) { 1683 // Read old file 1684 readStoppedLPw(); 1685 mBackupStoppedPackagesFilename.delete(); 1686 mStoppedPackagesFilename.delete(); 1687 // Migrate to new file format 1688 writePackageRestrictionsLPr(0); 1689 } else { 1690 if (users == null) { 1691 readPackageRestrictionsLPr(0); 1692 } else { 1693 for (UserInfo user : users) { 1694 readPackageRestrictionsLPr(user.id); 1695 } 1696 } 1697 } 1698 1699 final int N = mPendingPackages.size(); 1700 for (int i = 0; i < N; i++) { 1701 final PendingPackage pp = mPendingPackages.get(i); 1702 Object idObj = getUserIdLPr(pp.sharedId); 1703 if (idObj != null && idObj instanceof SharedUserSetting) { 1704 PackageSetting p = getPackageLPw(pp.name, null, pp.realName, 1705 (SharedUserSetting) idObj, pp.codePath, pp.resourcePath, 1706 pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags, 1707 UserHandle.ALL, true); 1708 if (p == null) { 1709 PackageManagerService.reportSettingsProblem(Log.WARN, 1710 "Unable to create application package for " + pp.name); 1711 continue; 1712 } 1713 p.copyFrom(pp); 1714 } else if (idObj != null) { 1715 String msg = "Bad package setting: package " + pp.name + " has shared uid " 1716 + pp.sharedId + " that is not a shared uid\n"; 1717 mReadMessages.append(msg); 1718 PackageManagerService.reportSettingsProblem(Log.ERROR, msg); 1719 } else { 1720 String msg = "Bad package setting: package " + pp.name + " has shared uid " 1721 + pp.sharedId + " that is not defined\n"; 1722 mReadMessages.append(msg); 1723 PackageManagerService.reportSettingsProblem(Log.ERROR, msg); 1724 } 1725 } 1726 mPendingPackages.clear(); 1727 1728 /* 1729 * Make sure all the updated system packages have their shared users 1730 * associated with them. 1731 */ 1732 final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator(); 1733 while (disabledIt.hasNext()) { 1734 final PackageSetting disabledPs = disabledIt.next(); 1735 final Object id = getUserIdLPr(disabledPs.appId); 1736 if (id != null && id instanceof SharedUserSetting) { 1737 disabledPs.sharedUser = (SharedUserSetting) id; 1738 } 1739 } 1740 1741 mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, " 1742 + mSharedUsers.size() + " shared uids\n"); 1743 1744 return true; 1745 } 1746 1747 private void readDefaultPreferredAppsLPw() { 1748 // Read preferred apps from .../etc/preferred-apps directory. 1749 File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps"); 1750 if (!preferredDir.exists() || !preferredDir.isDirectory()) { 1751 return; 1752 } 1753 if (!preferredDir.canRead()) { 1754 Slog.w(TAG, "Directory " + preferredDir + " cannot be read"); 1755 return; 1756 } 1757 1758 // Iterate over the files in the directory and scan .xml files 1759 for (File f : preferredDir.listFiles()) { 1760 if (!f.getPath().endsWith(".xml")) { 1761 Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring"); 1762 continue; 1763 } 1764 if (!f.canRead()) { 1765 Slog.w(TAG, "Preferred apps file " + f + " cannot be read"); 1766 continue; 1767 } 1768 1769 FileInputStream str = null; 1770 try { 1771 str = new FileInputStream(f); 1772 XmlPullParser parser = Xml.newPullParser(); 1773 parser.setInput(str, null); 1774 1775 int type; 1776 while ((type = parser.next()) != XmlPullParser.START_TAG 1777 && type != XmlPullParser.END_DOCUMENT) { 1778 ; 1779 } 1780 1781 if (type != XmlPullParser.START_TAG) { 1782 Slog.w(TAG, "Preferred apps file " + f + " does not have start tag"); 1783 continue; 1784 } 1785 if (!"preferred-activities".equals(parser.getName())) { 1786 Slog.w(TAG, "Preferred apps file " + f 1787 + " does not start with 'preferred-activities'"); 1788 continue; 1789 } 1790 readPreferredActivitiesLPw(parser); 1791 } catch (XmlPullParserException e) { 1792 Slog.w(TAG, "Error reading apps file " + f, e); 1793 } catch (IOException e) { 1794 Slog.w(TAG, "Error reading apps file " + f, e); 1795 } finally { 1796 if (str != null) { 1797 try { 1798 str.close(); 1799 } catch (IOException e) { 1800 } 1801 } 1802 } 1803 } 1804 } 1805 1806 private int readInt(XmlPullParser parser, String ns, String name, int defValue) { 1807 String v = parser.getAttributeValue(ns, name); 1808 try { 1809 if (v == null) { 1810 return defValue; 1811 } 1812 return Integer.parseInt(v); 1813 } catch (NumberFormatException e) { 1814 PackageManagerService.reportSettingsProblem(Log.WARN, 1815 "Error in package manager settings: attribute " + name 1816 + " has bad integer value " + v + " at " 1817 + parser.getPositionDescription()); 1818 } 1819 return defValue; 1820 } 1821 1822 private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser) 1823 throws IOException, XmlPullParserException { 1824 int outerDepth = parser.getDepth(); 1825 int type; 1826 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1827 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1828 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1829 continue; 1830 } 1831 1832 final String tagName = parser.getName(); 1833 if (tagName.equals(TAG_ITEM)) { 1834 final String name = parser.getAttributeValue(null, ATTR_NAME); 1835 final String sourcePackage = parser.getAttributeValue(null, "package"); 1836 final String ptype = parser.getAttributeValue(null, "type"); 1837 if (name != null && sourcePackage != null) { 1838 final boolean dynamic = "dynamic".equals(ptype); 1839 final BasePermission bp = new BasePermission(name, sourcePackage, 1840 dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL); 1841 bp.protectionLevel = readInt(parser, null, "protection", 1842 PermissionInfo.PROTECTION_NORMAL); 1843 bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel); 1844 if (dynamic) { 1845 PermissionInfo pi = new PermissionInfo(); 1846 pi.packageName = sourcePackage.intern(); 1847 pi.name = name.intern(); 1848 pi.icon = readInt(parser, null, "icon", 0); 1849 pi.nonLocalizedLabel = parser.getAttributeValue(null, "label"); 1850 pi.protectionLevel = bp.protectionLevel; 1851 bp.pendingInfo = pi; 1852 } 1853 out.put(bp.name, bp); 1854 } else { 1855 PackageManagerService.reportSettingsProblem(Log.WARN, 1856 "Error in package manager settings: permissions has" + " no name at " 1857 + parser.getPositionDescription()); 1858 } 1859 } else { 1860 PackageManagerService.reportSettingsProblem(Log.WARN, 1861 "Unknown element reading permissions: " + parser.getName() + " at " 1862 + parser.getPositionDescription()); 1863 } 1864 XmlUtils.skipCurrentTag(parser); 1865 } 1866 } 1867 1868 private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException, 1869 IOException { 1870 String name = parser.getAttributeValue(null, ATTR_NAME); 1871 String realName = parser.getAttributeValue(null, "realName"); 1872 String codePathStr = parser.getAttributeValue(null, "codePath"); 1873 String resourcePathStr = parser.getAttributeValue(null, "resourcePath"); 1874 String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath"); 1875 if (resourcePathStr == null) { 1876 resourcePathStr = codePathStr; 1877 } 1878 String version = parser.getAttributeValue(null, "version"); 1879 int versionCode = 0; 1880 if (version != null) { 1881 try { 1882 versionCode = Integer.parseInt(version); 1883 } catch (NumberFormatException e) { 1884 } 1885 } 1886 1887 int pkgFlags = 0; 1888 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 1889 PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), 1890 new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags); 1891 String timeStampStr = parser.getAttributeValue(null, "ft"); 1892 if (timeStampStr != null) { 1893 try { 1894 long timeStamp = Long.parseLong(timeStampStr, 16); 1895 ps.setTimeStamp(timeStamp); 1896 } catch (NumberFormatException e) { 1897 } 1898 } else { 1899 timeStampStr = parser.getAttributeValue(null, "ts"); 1900 if (timeStampStr != null) { 1901 try { 1902 long timeStamp = Long.parseLong(timeStampStr); 1903 ps.setTimeStamp(timeStamp); 1904 } catch (NumberFormatException e) { 1905 } 1906 } 1907 } 1908 timeStampStr = parser.getAttributeValue(null, "it"); 1909 if (timeStampStr != null) { 1910 try { 1911 ps.firstInstallTime = Long.parseLong(timeStampStr, 16); 1912 } catch (NumberFormatException e) { 1913 } 1914 } 1915 timeStampStr = parser.getAttributeValue(null, "ut"); 1916 if (timeStampStr != null) { 1917 try { 1918 ps.lastUpdateTime = Long.parseLong(timeStampStr, 16); 1919 } catch (NumberFormatException e) { 1920 } 1921 } 1922 String idStr = parser.getAttributeValue(null, "userId"); 1923 ps.appId = idStr != null ? Integer.parseInt(idStr) : 0; 1924 if (ps.appId <= 0) { 1925 String sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); 1926 ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0; 1927 } 1928 int outerDepth = parser.getDepth(); 1929 int type; 1930 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1931 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1932 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1933 continue; 1934 } 1935 1936 String tagName = parser.getName(); 1937 if (tagName.equals("perms")) { 1938 readGrantedPermissionsLPw(parser, ps.grantedPermissions); 1939 } else { 1940 PackageManagerService.reportSettingsProblem(Log.WARN, 1941 "Unknown element under <updated-package>: " + parser.getName()); 1942 XmlUtils.skipCurrentTag(parser); 1943 } 1944 } 1945 mDisabledSysPackages.put(name, ps); 1946 } 1947 1948 private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException { 1949 String name = null; 1950 String realName = null; 1951 String idStr = null; 1952 String sharedIdStr = null; 1953 String codePathStr = null; 1954 String resourcePathStr = null; 1955 String nativeLibraryPathStr = null; 1956 String systemStr = null; 1957 String installerPackageName = null; 1958 String uidError = null; 1959 int pkgFlags = 0; 1960 long timeStamp = 0; 1961 long firstInstallTime = 0; 1962 long lastUpdateTime = 0; 1963 PackageSettingBase packageSetting = null; 1964 String version = null; 1965 int versionCode = 0; 1966 try { 1967 name = parser.getAttributeValue(null, ATTR_NAME); 1968 realName = parser.getAttributeValue(null, "realName"); 1969 idStr = parser.getAttributeValue(null, "userId"); 1970 uidError = parser.getAttributeValue(null, "uidError"); 1971 sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); 1972 codePathStr = parser.getAttributeValue(null, "codePath"); 1973 resourcePathStr = parser.getAttributeValue(null, "resourcePath"); 1974 nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath"); 1975 version = parser.getAttributeValue(null, "version"); 1976 if (version != null) { 1977 try { 1978 versionCode = Integer.parseInt(version); 1979 } catch (NumberFormatException e) { 1980 } 1981 } 1982 installerPackageName = parser.getAttributeValue(null, "installer"); 1983 1984 systemStr = parser.getAttributeValue(null, "flags"); 1985 if (systemStr != null) { 1986 try { 1987 pkgFlags = Integer.parseInt(systemStr); 1988 } catch (NumberFormatException e) { 1989 } 1990 } else { 1991 // For backward compatibility 1992 systemStr = parser.getAttributeValue(null, "system"); 1993 if (systemStr != null) { 1994 pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM 1995 : 0; 1996 } else { 1997 // Old settings that don't specify system... just treat 1998 // them as system, good enough. 1999 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 2000 } 2001 } 2002 String timeStampStr = parser.getAttributeValue(null, "ft"); 2003 if (timeStampStr != null) { 2004 try { 2005 timeStamp = Long.parseLong(timeStampStr, 16); 2006 } catch (NumberFormatException e) { 2007 } 2008 } else { 2009 timeStampStr = parser.getAttributeValue(null, "ts"); 2010 if (timeStampStr != null) { 2011 try { 2012 timeStamp = Long.parseLong(timeStampStr); 2013 } catch (NumberFormatException e) { 2014 } 2015 } 2016 } 2017 timeStampStr = parser.getAttributeValue(null, "it"); 2018 if (timeStampStr != null) { 2019 try { 2020 firstInstallTime = Long.parseLong(timeStampStr, 16); 2021 } catch (NumberFormatException e) { 2022 } 2023 } 2024 timeStampStr = parser.getAttributeValue(null, "ut"); 2025 if (timeStampStr != null) { 2026 try { 2027 lastUpdateTime = Long.parseLong(timeStampStr, 16); 2028 } catch (NumberFormatException e) { 2029 } 2030 } 2031 if (PackageManagerService.DEBUG_SETTINGS) 2032 Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr 2033 + " sharedUserId=" + sharedIdStr); 2034 int userId = idStr != null ? Integer.parseInt(idStr) : 0; 2035 if (resourcePathStr == null) { 2036 resourcePathStr = codePathStr; 2037 } 2038 if (realName != null) { 2039 realName = realName.intern(); 2040 } 2041 if (name == null) { 2042 PackageManagerService.reportSettingsProblem(Log.WARN, 2043 "Error in package manager settings: <package> has no name at " 2044 + parser.getPositionDescription()); 2045 } else if (codePathStr == null) { 2046 PackageManagerService.reportSettingsProblem(Log.WARN, 2047 "Error in package manager settings: <package> has no codePath at " 2048 + parser.getPositionDescription()); 2049 } else if (userId > 0) { 2050 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr), 2051 new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode, 2052 pkgFlags); 2053 if (PackageManagerService.DEBUG_SETTINGS) 2054 Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId=" 2055 + userId + " pkg=" + packageSetting); 2056 if (packageSetting == null) { 2057 PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid " 2058 + userId + " while parsing settings at " 2059 + parser.getPositionDescription()); 2060 } else { 2061 packageSetting.setTimeStamp(timeStamp); 2062 packageSetting.firstInstallTime = firstInstallTime; 2063 packageSetting.lastUpdateTime = lastUpdateTime; 2064 } 2065 } else if (sharedIdStr != null) { 2066 userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0; 2067 if (userId > 0) { 2068 packageSetting = new PendingPackage(name.intern(), realName, new File( 2069 codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId, 2070 versionCode, pkgFlags); 2071 packageSetting.setTimeStamp(timeStamp); 2072 packageSetting.firstInstallTime = firstInstallTime; 2073 packageSetting.lastUpdateTime = lastUpdateTime; 2074 mPendingPackages.add((PendingPackage) packageSetting); 2075 if (PackageManagerService.DEBUG_SETTINGS) 2076 Log.i(PackageManagerService.TAG, "Reading package " + name 2077 + ": sharedUserId=" + userId + " pkg=" + packageSetting); 2078 } else { 2079 PackageManagerService.reportSettingsProblem(Log.WARN, 2080 "Error in package manager settings: package " + name 2081 + " has bad sharedId " + sharedIdStr + " at " 2082 + parser.getPositionDescription()); 2083 } 2084 } else { 2085 PackageManagerService.reportSettingsProblem(Log.WARN, 2086 "Error in package manager settings: package " + name + " has bad userId " 2087 + idStr + " at " + parser.getPositionDescription()); 2088 } 2089 } catch (NumberFormatException e) { 2090 PackageManagerService.reportSettingsProblem(Log.WARN, 2091 "Error in package manager settings: package " + name + " has bad userId " 2092 + idStr + " at " + parser.getPositionDescription()); 2093 } 2094 if (packageSetting != null) { 2095 packageSetting.uidError = "true".equals(uidError); 2096 packageSetting.installerPackageName = installerPackageName; 2097 packageSetting.nativeLibraryPathString = nativeLibraryPathStr; 2098 // Handle legacy string here for single-user mode 2099 final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED); 2100 if (enabledStr != null) { 2101 try { 2102 packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */); 2103 } catch (NumberFormatException e) { 2104 if (enabledStr.equalsIgnoreCase("true")) { 2105 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0); 2106 } else if (enabledStr.equalsIgnoreCase("false")) { 2107 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0); 2108 } else if (enabledStr.equalsIgnoreCase("default")) { 2109 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0); 2110 } else { 2111 PackageManagerService.reportSettingsProblem(Log.WARN, 2112 "Error in package manager settings: package " + name 2113 + " has bad enabled value: " + idStr + " at " 2114 + parser.getPositionDescription()); 2115 } 2116 } 2117 } else { 2118 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0); 2119 } 2120 2121 final String installStatusStr = parser.getAttributeValue(null, "installStatus"); 2122 if (installStatusStr != null) { 2123 if (installStatusStr.equalsIgnoreCase("false")) { 2124 packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE; 2125 } else { 2126 packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE; 2127 } 2128 } 2129 2130 int outerDepth = parser.getDepth(); 2131 int type; 2132 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2133 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2134 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2135 continue; 2136 } 2137 2138 String tagName = parser.getName(); 2139 // Legacy 2140 if (tagName.equals(TAG_DISABLED_COMPONENTS)) { 2141 readDisabledComponentsLPw(packageSetting, parser, 0); 2142 } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) { 2143 readEnabledComponentsLPw(packageSetting, parser, 0); 2144 } else if (tagName.equals("sigs")) { 2145 packageSetting.signatures.readXml(parser, mPastSignatures); 2146 } else if (tagName.equals("perms")) { 2147 readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions); 2148 packageSetting.permissionsFixed = true; 2149 } else { 2150 PackageManagerService.reportSettingsProblem(Log.WARN, 2151 "Unknown element under <package>: " + parser.getName()); 2152 XmlUtils.skipCurrentTag(parser); 2153 } 2154 } 2155 } else { 2156 XmlUtils.skipCurrentTag(parser); 2157 } 2158 } 2159 2160 private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, 2161 int userId) throws IOException, XmlPullParserException { 2162 int outerDepth = parser.getDepth(); 2163 int type; 2164 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2165 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2166 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2167 continue; 2168 } 2169 2170 String tagName = parser.getName(); 2171 if (tagName.equals(TAG_ITEM)) { 2172 String name = parser.getAttributeValue(null, ATTR_NAME); 2173 if (name != null) { 2174 packageSetting.addDisabledComponent(name.intern(), userId); 2175 } else { 2176 PackageManagerService.reportSettingsProblem(Log.WARN, 2177 "Error in package manager settings: <disabled-components> has" 2178 + " no name at " + parser.getPositionDescription()); 2179 } 2180 } else { 2181 PackageManagerService.reportSettingsProblem(Log.WARN, 2182 "Unknown element under <disabled-components>: " + parser.getName()); 2183 } 2184 XmlUtils.skipCurrentTag(parser); 2185 } 2186 } 2187 2188 private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, 2189 int userId) throws IOException, XmlPullParserException { 2190 int outerDepth = parser.getDepth(); 2191 int type; 2192 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2193 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2194 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2195 continue; 2196 } 2197 2198 String tagName = parser.getName(); 2199 if (tagName.equals(TAG_ITEM)) { 2200 String name = parser.getAttributeValue(null, ATTR_NAME); 2201 if (name != null) { 2202 packageSetting.addEnabledComponent(name.intern(), userId); 2203 } else { 2204 PackageManagerService.reportSettingsProblem(Log.WARN, 2205 "Error in package manager settings: <enabled-components> has" 2206 + " no name at " + parser.getPositionDescription()); 2207 } 2208 } else { 2209 PackageManagerService.reportSettingsProblem(Log.WARN, 2210 "Unknown element under <enabled-components>: " + parser.getName()); 2211 } 2212 XmlUtils.skipCurrentTag(parser); 2213 } 2214 } 2215 2216 private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException { 2217 String name = null; 2218 String idStr = null; 2219 int pkgFlags = 0; 2220 SharedUserSetting su = null; 2221 try { 2222 name = parser.getAttributeValue(null, ATTR_NAME); 2223 idStr = parser.getAttributeValue(null, "userId"); 2224 int userId = idStr != null ? Integer.parseInt(idStr) : 0; 2225 if ("true".equals(parser.getAttributeValue(null, "system"))) { 2226 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 2227 } 2228 if (name == null) { 2229 PackageManagerService.reportSettingsProblem(Log.WARN, 2230 "Error in package manager settings: <shared-user> has no name at " 2231 + parser.getPositionDescription()); 2232 } else if (userId == 0) { 2233 PackageManagerService.reportSettingsProblem(Log.WARN, 2234 "Error in package manager settings: shared-user " + name 2235 + " has bad userId " + idStr + " at " 2236 + parser.getPositionDescription()); 2237 } else { 2238 if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) { 2239 PackageManagerService 2240 .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at " 2241 + parser.getPositionDescription()); 2242 } 2243 } 2244 } catch (NumberFormatException e) { 2245 PackageManagerService.reportSettingsProblem(Log.WARN, 2246 "Error in package manager settings: package " + name + " has bad userId " 2247 + idStr + " at " + parser.getPositionDescription()); 2248 } 2249 ; 2250 2251 if (su != null) { 2252 int outerDepth = parser.getDepth(); 2253 int type; 2254 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2255 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2256 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2257 continue; 2258 } 2259 2260 String tagName = parser.getName(); 2261 if (tagName.equals("sigs")) { 2262 su.signatures.readXml(parser, mPastSignatures); 2263 } else if (tagName.equals("perms")) { 2264 readGrantedPermissionsLPw(parser, su.grantedPermissions); 2265 } else { 2266 PackageManagerService.reportSettingsProblem(Log.WARN, 2267 "Unknown element under <shared-user>: " + parser.getName()); 2268 XmlUtils.skipCurrentTag(parser); 2269 } 2270 } 2271 2272 } else { 2273 XmlUtils.skipCurrentTag(parser); 2274 } 2275 } 2276 2277 private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms) 2278 throws IOException, XmlPullParserException { 2279 int outerDepth = parser.getDepth(); 2280 int type; 2281 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2282 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2283 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2284 continue; 2285 } 2286 2287 String tagName = parser.getName(); 2288 if (tagName.equals(TAG_ITEM)) { 2289 String name = parser.getAttributeValue(null, ATTR_NAME); 2290 if (name != null) { 2291 outPerms.add(name.intern()); 2292 } else { 2293 PackageManagerService.reportSettingsProblem(Log.WARN, 2294 "Error in package manager settings: <perms> has" + " no name at " 2295 + parser.getPositionDescription()); 2296 } 2297 } else { 2298 PackageManagerService.reportSettingsProblem(Log.WARN, 2299 "Unknown element under <perms>: " + parser.getName()); 2300 } 2301 XmlUtils.skipCurrentTag(parser); 2302 } 2303 } 2304 2305 private void readPreferredActivitiesLPw(XmlPullParser parser) throws XmlPullParserException, 2306 IOException { 2307 int outerDepth = parser.getDepth(); 2308 int type; 2309 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2310 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2311 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2312 continue; 2313 } 2314 2315 String tagName = parser.getName(); 2316 if (tagName.equals(TAG_ITEM)) { 2317 PreferredActivity pa = new PreferredActivity(parser); 2318 if (pa.mPref.getParseError() == null) { 2319 mPreferredActivities.addFilter(pa); 2320 } else { 2321 PackageManagerService.reportSettingsProblem(Log.WARN, 2322 "Error in package manager settings: <preferred-activity> " 2323 + pa.mPref.getParseError() + " at " 2324 + parser.getPositionDescription()); 2325 } 2326 } else { 2327 PackageManagerService.reportSettingsProblem(Log.WARN, 2328 "Unknown element under <preferred-activities>: " + parser.getName()); 2329 XmlUtils.skipCurrentTag(parser); 2330 } 2331 } 2332 } 2333 2334 void removeUserLPr(int userId) { 2335 File file = getUserPackagesStateFile(userId); 2336 file.delete(); 2337 file = getUserPackagesStateBackupFile(userId); 2338 file.delete(); 2339 } 2340 2341 // Returns -1 if we could not find an available UserId to assign 2342 private int newUserIdLPw(Object obj) { 2343 // Let's be stupidly inefficient for now... 2344 final int N = mUserIds.size(); 2345 for (int i = 0; i < N; i++) { 2346 if (mUserIds.get(i) == null) { 2347 mUserIds.set(i, obj); 2348 return Process.FIRST_APPLICATION_UID + i; 2349 } 2350 } 2351 2352 // None left? 2353 if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) { 2354 return -1; 2355 } 2356 2357 mUserIds.add(obj); 2358 return Process.FIRST_APPLICATION_UID + N; 2359 } 2360 2361 public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() { 2362 if (mVerifierDeviceIdentity == null) { 2363 mVerifierDeviceIdentity = VerifierDeviceIdentity.generate(); 2364 2365 writeLPr(); 2366 } 2367 2368 return mVerifierDeviceIdentity; 2369 } 2370 2371 public PackageSetting getDisabledSystemPkgLPr(String name) { 2372 PackageSetting ps = mDisabledSysPackages.get(name); 2373 return ps; 2374 } 2375 2376 private String compToString(HashSet<String> cmp) { 2377 return cmp != null ? Arrays.toString(cmp.toArray()) : "[]"; 2378 } 2379 2380 boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) { 2381 if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) { 2382 return true; 2383 } 2384 final String pkgName = componentInfo.packageName; 2385 final PackageSetting packageSettings = mPackages.get(pkgName); 2386 if (PackageManagerService.DEBUG_SETTINGS) { 2387 Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = " 2388 + componentInfo.packageName + " componentName = " + componentInfo.name); 2389 Log.v(PackageManagerService.TAG, "enabledComponents: " 2390 + compToString(packageSettings.getEnabledComponents(userId))); 2391 Log.v(PackageManagerService.TAG, "disabledComponents: " 2392 + compToString(packageSettings.getDisabledComponents(userId))); 2393 } 2394 if (packageSettings == null) { 2395 return false; 2396 } 2397 PackageUserState ustate = packageSettings.readUserState(userId); 2398 if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED 2399 || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER 2400 || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled 2401 && ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) { 2402 return false; 2403 } 2404 if (ustate.enabledComponents != null 2405 && ustate.enabledComponents.contains(componentInfo.name)) { 2406 return true; 2407 } 2408 if (ustate.disabledComponents != null 2409 && ustate.disabledComponents.contains(componentInfo.name)) { 2410 return false; 2411 } 2412 return componentInfo.enabled; 2413 } 2414 2415 String getInstallerPackageNameLPr(String packageName) { 2416 final PackageSetting pkg = mPackages.get(packageName); 2417 if (pkg == null) { 2418 throw new IllegalArgumentException("Unknown package: " + packageName); 2419 } 2420 return pkg.installerPackageName; 2421 } 2422 2423 int getApplicationEnabledSettingLPr(String packageName, int userId) { 2424 final PackageSetting pkg = mPackages.get(packageName); 2425 if (pkg == null) { 2426 throw new IllegalArgumentException("Unknown package: " + packageName); 2427 } 2428 return pkg.getEnabled(userId); 2429 } 2430 2431 int getComponentEnabledSettingLPr(ComponentName componentName, int userId) { 2432 final String packageName = componentName.getPackageName(); 2433 final PackageSetting pkg = mPackages.get(packageName); 2434 if (pkg == null) { 2435 throw new IllegalArgumentException("Unknown component: " + componentName); 2436 } 2437 final String classNameStr = componentName.getClassName(); 2438 return pkg.getCurrentEnabledStateLPr(classNameStr, userId); 2439 } 2440 2441 boolean setPackageStoppedStateLPw(String packageName, boolean stopped, 2442 boolean allowedByPermission, int uid, int userId) { 2443 int appId = UserHandle.getAppId(uid); 2444 final PackageSetting pkgSetting = mPackages.get(packageName); 2445 if (pkgSetting == null) { 2446 throw new IllegalArgumentException("Unknown package: " + packageName); 2447 } 2448 if (!allowedByPermission && (appId != pkgSetting.appId)) { 2449 throw new SecurityException( 2450 "Permission Denial: attempt to change stopped state from pid=" 2451 + Binder.getCallingPid() 2452 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 2453 } 2454 if (DEBUG_STOPPED) { 2455 if (stopped) { 2456 RuntimeException e = new RuntimeException("here"); 2457 e.fillInStackTrace(); 2458 Slog.i(TAG, "Stopping package " + packageName, e); 2459 } 2460 } 2461 if (pkgSetting.getStopped(userId) != stopped) { 2462 pkgSetting.setStopped(stopped, userId); 2463 // pkgSetting.pkg.mSetStopped = stopped; 2464 if (pkgSetting.getNotLaunched(userId)) { 2465 if (pkgSetting.installerPackageName != null) { 2466 PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, 2467 pkgSetting.name, null, 2468 pkgSetting.installerPackageName, null, new int[] {userId}); 2469 } 2470 pkgSetting.setNotLaunched(false, userId); 2471 } 2472 return true; 2473 } 2474 return false; 2475 } 2476 2477 private List<UserInfo> getAllUsers() { 2478 long id = Binder.clearCallingIdentity(); 2479 try { 2480 return UserManagerService.getInstance().getUsers(); 2481 } catch (NullPointerException npe) { 2482 // packagemanager not yet initialized 2483 } finally { 2484 Binder.restoreCallingIdentity(id); 2485 } 2486 return null; 2487 } 2488 2489 static final void printFlags(PrintWriter pw, int val, Object[] spec) { 2490 pw.print("[ "); 2491 for (int i=0; i<spec.length; i+=2) { 2492 int mask = (Integer)spec[i]; 2493 if ((val & mask) != 0) { 2494 pw.print(spec[i+1]); 2495 pw.print(" "); 2496 } 2497 } 2498 pw.print("]"); 2499 } 2500 2501 static final Object[] FLAG_DUMP_SPEC = new Object[] { 2502 ApplicationInfo.FLAG_SYSTEM, "SYSTEM", 2503 ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE", 2504 ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE", 2505 ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT", 2506 ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST", 2507 ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING", 2508 ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA", 2509 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP", 2510 ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY", 2511 ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE", 2512 ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP", 2513 ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE", 2514 ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION", 2515 ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE", 2516 ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP", 2517 ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK", 2518 ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE", 2519 }; 2520 2521 void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState) { 2522 final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 2523 final Date date = new Date(); 2524 boolean printedSomething = false; 2525 List<UserInfo> users = getAllUsers(); 2526 for (final PackageSetting ps : mPackages.values()) { 2527 if (packageName != null && !packageName.equals(ps.realName) 2528 && !packageName.equals(ps.name)) { 2529 continue; 2530 } 2531 2532 if (packageName != null) { 2533 dumpState.setSharedUser(ps.sharedUser); 2534 } 2535 2536 if (!printedSomething) { 2537 if (dumpState.onTitlePrinted()) 2538 pw.println(" "); 2539 pw.println("Packages:"); 2540 printedSomething = true; 2541 } 2542 pw.print(" Package ["); 2543 pw.print(ps.realName != null ? ps.realName : ps.name); 2544 pw.print("] ("); 2545 pw.print(Integer.toHexString(System.identityHashCode(ps))); 2546 pw.println("):"); 2547 2548 if (ps.realName != null) { 2549 pw.print(" compat name="); 2550 pw.println(ps.name); 2551 } 2552 2553 pw.print(" userId="); pw.print(ps.appId); 2554 pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids)); 2555 pw.print(" sharedUser="); pw.println(ps.sharedUser); 2556 pw.print(" pkg="); pw.println(ps.pkg); 2557 pw.print(" codePath="); pw.println(ps.codePathString); 2558 pw.print(" resourcePath="); pw.println(ps.resourcePathString); 2559 pw.print(" nativeLibraryPath="); pw.println(ps.nativeLibraryPathString); 2560 pw.print(" versionCode="); pw.println(ps.versionCode); 2561 if (ps.pkg != null) { 2562 pw.print(" applicationInfo="); pw.println(ps.pkg.applicationInfo.toString()); 2563 pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags, FLAG_DUMP_SPEC); pw.println(); 2564 pw.print(" versionName="); pw.println(ps.pkg.mVersionName); 2565 pw.print(" dataDir="); pw.println(ps.pkg.applicationInfo.dataDir); 2566 pw.print(" targetSdk="); pw.println(ps.pkg.applicationInfo.targetSdkVersion); 2567 if (ps.pkg.mOperationPending) { 2568 pw.println(" mOperationPending=true"); 2569 } 2570 pw.print(" supportsScreens=["); 2571 boolean first = true; 2572 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) { 2573 if (!first) 2574 pw.print(", "); 2575 first = false; 2576 pw.print("small"); 2577 } 2578 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) { 2579 if (!first) 2580 pw.print(", "); 2581 first = false; 2582 pw.print("medium"); 2583 } 2584 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { 2585 if (!first) 2586 pw.print(", "); 2587 first = false; 2588 pw.print("large"); 2589 } 2590 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { 2591 if (!first) 2592 pw.print(", "); 2593 first = false; 2594 pw.print("xlarge"); 2595 } 2596 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { 2597 if (!first) 2598 pw.print(", "); 2599 first = false; 2600 pw.print("resizeable"); 2601 } 2602 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { 2603 if (!first) 2604 pw.print(", "); 2605 first = false; 2606 pw.print("anyDensity"); 2607 } 2608 pw.println("]"); 2609 } 2610 pw.print(" timeStamp="); 2611 date.setTime(ps.timeStamp); 2612 pw.println(sdf.format(date)); 2613 pw.print(" firstInstallTime="); 2614 date.setTime(ps.firstInstallTime); 2615 pw.println(sdf.format(date)); 2616 pw.print(" lastUpdateTime="); 2617 date.setTime(ps.lastUpdateTime); 2618 pw.println(sdf.format(date)); 2619 if (ps.installerPackageName != null) { 2620 pw.print(" installerPackageName="); pw.println(ps.installerPackageName); 2621 } 2622 pw.print(" signatures="); pw.println(ps.signatures); 2623 pw.print(" permissionsFixed="); pw.println(ps.permissionsFixed); 2624 pw.print(" haveGids="); pw.println(ps.haveGids); 2625 pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC); 2626 pw.print(" installStatus="); pw.println(ps.installStatus); 2627 for (UserInfo user : users) { 2628 pw.print(" User "); pw.print(user.id); pw.print(": "); 2629 pw.print(" installed="); 2630 pw.print(ps.getInstalled(user.id)); 2631 pw.print(" stopped="); 2632 pw.print(ps.getStopped(user.id)); 2633 pw.print(" notLaunched="); 2634 pw.print(ps.getNotLaunched(user.id)); 2635 pw.print(" enabled="); 2636 pw.println(ps.getEnabled(user.id)); 2637 HashSet<String> cmp = ps.getDisabledComponents(user.id); 2638 if (cmp != null && cmp.size() > 0) { 2639 pw.println(" disabledComponents:"); 2640 for (String s : cmp) { 2641 pw.print(" "); pw.println(s); 2642 } 2643 } 2644 cmp = ps.getEnabledComponents(user.id); 2645 if (cmp != null && cmp.size() > 0) { 2646 pw.println(" enabledComponents:"); 2647 for (String s : cmp) { 2648 pw.print(" "); pw.println(s); 2649 } 2650 } 2651 } 2652 if (ps.grantedPermissions.size() > 0) { 2653 pw.println(" grantedPermissions:"); 2654 for (String s : ps.grantedPermissions) { 2655 pw.print(" "); pw.println(s); 2656 } 2657 } 2658 } 2659 2660 printedSomething = false; 2661 if (mRenamedPackages.size() > 0) { 2662 for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) { 2663 if (packageName != null && !packageName.equals(e.getKey()) 2664 && !packageName.equals(e.getValue())) { 2665 continue; 2666 } 2667 if (!printedSomething) { 2668 if (dumpState.onTitlePrinted()) 2669 pw.println(" "); 2670 pw.println("Renamed packages:"); 2671 printedSomething = true; 2672 } 2673 pw.print(" "); 2674 pw.print(e.getKey()); 2675 pw.print(" -> "); 2676 pw.println(e.getValue()); 2677 } 2678 } 2679 2680 printedSomething = false; 2681 if (mDisabledSysPackages.size() > 0) { 2682 for (final PackageSetting ps : mDisabledSysPackages.values()) { 2683 if (packageName != null && !packageName.equals(ps.realName) 2684 && !packageName.equals(ps.name)) { 2685 continue; 2686 } 2687 if (!printedSomething) { 2688 if (dumpState.onTitlePrinted()) 2689 pw.println(" "); 2690 pw.println("Hidden system packages:"); 2691 printedSomething = true; 2692 } 2693 pw.print(" Package ["); 2694 pw.print(ps.realName != null ? ps.realName : ps.name); 2695 pw.print("] ("); 2696 pw.print(Integer.toHexString(System.identityHashCode(ps))); 2697 pw.println("):"); 2698 if (ps.realName != null) { 2699 pw.print(" compat name="); 2700 pw.println(ps.name); 2701 } 2702 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 2703 pw.print(" applicationInfo="); 2704 pw.println(ps.pkg.applicationInfo.toString()); 2705 } 2706 pw.print(" userId="); 2707 pw.println(ps.appId); 2708 pw.print(" sharedUser="); 2709 pw.println(ps.sharedUser); 2710 pw.print(" codePath="); 2711 pw.println(ps.codePathString); 2712 pw.print(" resourcePath="); 2713 pw.println(ps.resourcePathString); 2714 } 2715 } 2716 } 2717 2718 void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) { 2719 boolean printedSomething = false; 2720 for (BasePermission p : mPermissions.values()) { 2721 if (packageName != null && !packageName.equals(p.sourcePackage)) { 2722 continue; 2723 } 2724 if (!printedSomething) { 2725 if (dumpState.onTitlePrinted()) 2726 pw.println(" "); 2727 pw.println("Permissions:"); 2728 printedSomething = true; 2729 } 2730 pw.print(" Permission ["); pw.print(p.name); pw.print("] ("); 2731 pw.print(Integer.toHexString(System.identityHashCode(p))); 2732 pw.println("):"); 2733 pw.print(" sourcePackage="); pw.println(p.sourcePackage); 2734 pw.print(" uid="); pw.print(p.uid); 2735 pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids)); 2736 pw.print(" type="); pw.print(p.type); 2737 pw.print(" prot="); 2738 pw.println(PermissionInfo.protectionToString(p.protectionLevel)); 2739 if (p.packageSetting != null) { 2740 pw.print(" packageSetting="); pw.println(p.packageSetting); 2741 } 2742 if (p.perm != null) { 2743 pw.print(" perm="); pw.println(p.perm); 2744 } 2745 if (READ_EXTERNAL_STORAGE.equals(p.name)) { 2746 pw.print(" enforced="); 2747 pw.println(mReadExternalStorageEnforced); 2748 } 2749 } 2750 } 2751 2752 void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) { 2753 boolean printedSomething = false; 2754 for (SharedUserSetting su : mSharedUsers.values()) { 2755 if (packageName != null && su != dumpState.getSharedUser()) { 2756 continue; 2757 } 2758 if (!printedSomething) { 2759 if (dumpState.onTitlePrinted()) 2760 pw.println(" "); 2761 pw.println("Shared users:"); 2762 printedSomething = true; 2763 } 2764 pw.print(" SharedUser ["); 2765 pw.print(su.name); 2766 pw.print("] ("); 2767 pw.print(Integer.toHexString(System.identityHashCode(su))); 2768 pw.println("):"); 2769 pw.print(" userId="); 2770 pw.print(su.userId); 2771 pw.print(" gids="); 2772 pw.println(PackageManagerService.arrayToString(su.gids)); 2773 pw.println(" grantedPermissions:"); 2774 for (String s : su.grantedPermissions) { 2775 pw.print(" "); 2776 pw.println(s); 2777 } 2778 } 2779 } 2780 2781 void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) { 2782 pw.println("Settings parse messages:"); 2783 pw.print(mReadMessages.toString()); 2784 } 2785} 2786