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