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 Settings()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 getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String nativeLibraryPathString, int pkgFlags, boolean create, boolean add)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 peekPackageLPr(String name)171 PackageSetting peekPackageLPr(String name) { 172 return mPackages.get(name); 173 } 174 setInstallStatus(String pkgName, int status)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 setInstallerPackageName(String pkgName, String installerPkgName)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 getSharedUserLPw(String name, int pkgFlags, boolean create)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 disableSystemPackageLPw(String name)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 enableSystemPackageLPw(String name)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 addPackageLPw(String name, String realName, File codePath, File resourcePath, String nativeLibraryPathString, int uid, int vc, int pkgFlags)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 addSharedUserLPw(String name, int uid, int pkgFlags)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. transferPermissionsLPw(String origPkg, String newPkg)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 getPackageLPw(String name, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add)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 insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg)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 addPackageSettingLPw(PackageSetting p, String name, SharedUserSetting sharedUser)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 */ updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids)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 removePackageLPw(String name)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 replacePackageLPw(String name, PackageSetting newp)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 addUserIdLPw(int uid, Object obj, Object name)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 getUserIdLPr(int uid)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 removeUserIdLPw(int uid)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 replaceUserIdLPw(int uid, Object obj)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 writeStoppedLPr()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. readStoppedLPw()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 writeLPr()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 writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)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 writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)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 writePermissionLPr(XmlSerializer serializer, BasePermission bp)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 getListOfIncompleteInstallPackagesLPr()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 readLPw()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 readInt(XmlPullParser parser, String ns, String name, int defValue)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 readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)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 readDisabledSysPackageLPw(XmlPullParser parser)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 readPackageLPw(XmlPullParser parser)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 readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)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 readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)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 readSharedUserLPw(XmlPullParser parser)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 readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)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 readPreferredActivitiesLPw(XmlPullParser parser)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 newUserIdLPw(Object obj)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 getVerifierDeviceIdentityLPw()1914 public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() { 1915 if (mVerifierDeviceIdentity == null) { 1916 mVerifierDeviceIdentity = VerifierDeviceIdentity.generate(); 1917 1918 writeLPr(); 1919 } 1920 1921 return mVerifierDeviceIdentity; 1922 } 1923 getDisabledSystemPkgLPr(String name)1924 public PackageSetting getDisabledSystemPkgLPr(String name) { 1925 PackageSetting ps = mDisabledSysPackages.get(name); 1926 return ps; 1927 } 1928 isEnabledLPr(ComponentInfo componentInfo, int flags)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 getInstallerPackageNameLPr(String packageName)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 getApplicationEnabledSettingLPr(String packageName)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 getComponentEnabledSettingLPr(ComponentName componentName)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 setPackageStoppedStateLPw(String packageName, boolean stopped, boolean allowedByPermission, int uid)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 dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState)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 dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState)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 dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState)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 dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState)2258 void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) { 2259 pw.println("Settings parse messages:"); 2260 pw.print(mReadMessages.toString()); 2261 } 2262 }