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