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