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