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