1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm; 18 19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 22 23 import android.content.pm.ApplicationInfo; 24 import android.content.pm.IntentFilterVerificationInfo; 25 import android.content.pm.PackageManager; 26 import android.content.pm.PackageUserState; 27 import android.os.storage.VolumeInfo; 28 import android.service.pm.PackageProto; 29 import android.util.ArraySet; 30 import android.util.SparseArray; 31 import android.util.proto.ProtoOutputStream; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.google.android.collect.Lists; 35 36 import java.io.File; 37 import java.util.ArrayList; 38 import java.util.Arrays; 39 import java.util.List; 40 import java.util.Set; 41 42 /** 43 * Settings base class for pending and resolved classes. 44 */ 45 abstract class PackageSettingBase extends SettingBase { 46 47 private static final int[] EMPTY_INT_ARRAY = new int[0]; 48 49 /** 50 * Indicates the state of installation. Used by PackageManager to figure out 51 * incomplete installations. Say a package is being installed (the state is 52 * set to PKG_INSTALL_INCOMPLETE) and remains so till the package 53 * installation is successful or unsuccessful in which case the 54 * PackageManager will no longer maintain state information associated with 55 * the package. If some exception(like device freeze or battery being pulled 56 * out) occurs during installation of a package, the PackageManager needs 57 * this information to clean up the previously failed installation. 58 */ 59 static final int PKG_INSTALL_COMPLETE = 1; 60 static final int PKG_INSTALL_INCOMPLETE = 0; 61 62 final String name; 63 final String realName; 64 65 String parentPackageName; 66 List<String> childPackageNames; 67 68 /** 69 * Path where this package was found on disk. For monolithic packages 70 * this is path to single base APK file; for cluster packages this is 71 * path to the cluster directory. 72 */ 73 File codePath; 74 String codePathString; 75 File resourcePath; 76 String resourcePathString; 77 78 String[] usesStaticLibraries; 79 int[] usesStaticLibrariesVersions; 80 81 /** 82 * The path under which native libraries have been unpacked. This path is 83 * always derived at runtime, and is only stored here for cleanup when a 84 * package is uninstalled. 85 */ 86 @Deprecated 87 String legacyNativeLibraryPathString; 88 89 /** 90 * The primary CPU abi for this package. 91 */ 92 String primaryCpuAbiString; 93 94 /** 95 * The secondary CPU abi for this package. 96 */ 97 String secondaryCpuAbiString; 98 99 /** 100 * The install time CPU override, if any. This value is written at install time 101 * and doesn't change during the life of an install. If non-null, 102 * {@code primaryCpuAbiString} will contain the same value. 103 */ 104 String cpuAbiOverrideString; 105 106 long timeStamp; 107 long firstInstallTime; 108 long lastUpdateTime; 109 int versionCode; 110 111 boolean uidError; 112 113 PackageSignatures signatures; 114 115 boolean installPermissionsFixed; 116 117 PackageKeySetData keySetData = new PackageKeySetData(); 118 119 static final PackageUserState DEFAULT_USER_STATE = new PackageUserState(); 120 121 // Whether this package is currently stopped, thus can not be 122 // started until explicitly launched by the user. 123 private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>(); 124 125 int installStatus = PKG_INSTALL_COMPLETE; 126 127 /** 128 * Non-persisted value. During an "upgrade without restart", we need the set 129 * of all previous code paths so we can surgically add the new APKs to the 130 * active classloader. If at any point an application is upgraded with a 131 * restart, this field will be cleared since the classloader would be created 132 * using the full set of code paths when the package's process is started. 133 */ 134 Set<String> oldCodePaths; 135 PackageSettingBase origPackage; 136 137 /** Package name of the app that installed this package */ 138 String installerPackageName; 139 /** Indicates if the package that installed this app has been uninstalled */ 140 boolean isOrphaned; 141 /** UUID of {@link VolumeInfo} hosting this app */ 142 String volumeUuid; 143 /** The category of this app, as hinted by the installer */ 144 int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED; 145 /** Whether or not an update is available. Ostensibly only for instant apps. */ 146 boolean updateAvailable; 147 148 IntentFilterVerificationInfo verificationInfo; 149 PackageSettingBase(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int pVersionCode, int pkgFlags, int pkgPrivateFlags, String parentPackageName, List<String> childPackageNames, String[] usesStaticLibraries, int[] usesStaticLibrariesVersions)150 PackageSettingBase(String name, String realName, File codePath, File resourcePath, 151 String legacyNativeLibraryPathString, String primaryCpuAbiString, 152 String secondaryCpuAbiString, String cpuAbiOverrideString, 153 int pVersionCode, int pkgFlags, int pkgPrivateFlags, 154 String parentPackageName, List<String> childPackageNames, 155 String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) { 156 super(pkgFlags, pkgPrivateFlags); 157 this.name = name; 158 this.realName = realName; 159 this.parentPackageName = parentPackageName; 160 this.childPackageNames = (childPackageNames != null) 161 ? new ArrayList<>(childPackageNames) : null; 162 this.usesStaticLibraries = usesStaticLibraries; 163 this.usesStaticLibrariesVersions = usesStaticLibrariesVersions; 164 init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, 165 secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode); 166 } 167 168 /** 169 * New instance of PackageSetting with one-level-deep cloning. 170 * <p> 171 * IMPORTANT: With a shallow copy, we do NOT create new contained objects. 172 * This means, for example, changes to the user state of the original PackageSetting 173 * will also change the user state in its copy. 174 */ PackageSettingBase(PackageSettingBase base, String realName)175 PackageSettingBase(PackageSettingBase base, String realName) { 176 super(base); 177 name = base.name; 178 this.realName = realName; 179 doCopy(base); 180 } 181 init(File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int pVersionCode)182 void init(File codePath, File resourcePath, String legacyNativeLibraryPathString, 183 String primaryCpuAbiString, String secondaryCpuAbiString, 184 String cpuAbiOverrideString, int pVersionCode) { 185 this.codePath = codePath; 186 this.codePathString = codePath.toString(); 187 this.resourcePath = resourcePath; 188 this.resourcePathString = resourcePath.toString(); 189 this.legacyNativeLibraryPathString = legacyNativeLibraryPathString; 190 this.primaryCpuAbiString = primaryCpuAbiString; 191 this.secondaryCpuAbiString = secondaryCpuAbiString; 192 this.cpuAbiOverrideString = cpuAbiOverrideString; 193 this.versionCode = pVersionCode; 194 this.signatures = new PackageSignatures(); 195 } 196 setInstallerPackageName(String packageName)197 public void setInstallerPackageName(String packageName) { 198 installerPackageName = packageName; 199 } 200 getInstallerPackageName()201 public String getInstallerPackageName() { 202 return installerPackageName; 203 } 204 setVolumeUuid(String volumeUuid)205 public void setVolumeUuid(String volumeUuid) { 206 this.volumeUuid = volumeUuid; 207 } 208 getVolumeUuid()209 public String getVolumeUuid() { 210 return volumeUuid; 211 } 212 setInstallStatus(int newStatus)213 public void setInstallStatus(int newStatus) { 214 installStatus = newStatus; 215 } 216 getInstallStatus()217 public int getInstallStatus() { 218 return installStatus; 219 } 220 setTimeStamp(long newStamp)221 public void setTimeStamp(long newStamp) { 222 timeStamp = newStamp; 223 } 224 setUpdateAvailable(boolean updateAvailable)225 public void setUpdateAvailable(boolean updateAvailable) { 226 this.updateAvailable = updateAvailable; 227 } 228 isUpdateAvailable()229 public boolean isUpdateAvailable() { 230 return updateAvailable; 231 } 232 233 /** 234 * Makes a shallow copy of the given package settings. 235 * 236 * NOTE: For some fields [such as keySetData, signatures, userState, verificationInfo, etc...], 237 * the original object is copied and a new one is not created. 238 */ copyFrom(PackageSettingBase orig)239 public void copyFrom(PackageSettingBase orig) { 240 super.copyFrom(orig); 241 doCopy(orig); 242 } 243 doCopy(PackageSettingBase orig)244 private void doCopy(PackageSettingBase orig) { 245 childPackageNames = (orig.childPackageNames != null) 246 ? new ArrayList<>(orig.childPackageNames) : null; 247 codePath = orig.codePath; 248 codePathString = orig.codePathString; 249 cpuAbiOverrideString = orig.cpuAbiOverrideString; 250 firstInstallTime = orig.firstInstallTime; 251 installPermissionsFixed = orig.installPermissionsFixed; 252 installStatus = orig.installStatus; 253 installerPackageName = orig.installerPackageName; 254 isOrphaned = orig.isOrphaned; 255 keySetData = orig.keySetData; 256 lastUpdateTime = orig.lastUpdateTime; 257 legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString; 258 // Intentionally skip oldCodePaths; it's not relevant for copies 259 origPackage = orig.origPackage; 260 parentPackageName = orig.parentPackageName; 261 primaryCpuAbiString = orig.primaryCpuAbiString; 262 resourcePath = orig.resourcePath; 263 resourcePathString = orig.resourcePathString; 264 secondaryCpuAbiString = orig.secondaryCpuAbiString; 265 signatures = orig.signatures; 266 timeStamp = orig.timeStamp; 267 uidError = orig.uidError; 268 userState.clear(); 269 for (int i=0; i<orig.userState.size(); i++) { 270 userState.put(orig.userState.keyAt(i), orig.userState.valueAt(i)); 271 } 272 verificationInfo = orig.verificationInfo; 273 versionCode = orig.versionCode; 274 volumeUuid = orig.volumeUuid; 275 categoryHint = orig.categoryHint; 276 usesStaticLibraries = orig.usesStaticLibraries != null 277 ? Arrays.copyOf(orig.usesStaticLibraries, 278 orig.usesStaticLibraries.length) : null; 279 usesStaticLibrariesVersions = orig.usesStaticLibrariesVersions != null 280 ? Arrays.copyOf(orig.usesStaticLibrariesVersions, 281 orig.usesStaticLibrariesVersions.length) : null; 282 updateAvailable = orig.updateAvailable; 283 } 284 modifyUserState(int userId)285 private PackageUserState modifyUserState(int userId) { 286 PackageUserState state = userState.get(userId); 287 if (state == null) { 288 state = new PackageUserState(); 289 userState.put(userId, state); 290 } 291 return state; 292 } 293 readUserState(int userId)294 public PackageUserState readUserState(int userId) { 295 PackageUserState state = userState.get(userId); 296 if (state == null) { 297 return DEFAULT_USER_STATE; 298 } 299 state.categoryHint = categoryHint; 300 return state; 301 } 302 setEnabled(int state, int userId, String callingPackage)303 void setEnabled(int state, int userId, String callingPackage) { 304 PackageUserState st = modifyUserState(userId); 305 st.enabled = state; 306 st.lastDisableAppCaller = callingPackage; 307 } 308 getEnabled(int userId)309 int getEnabled(int userId) { 310 return readUserState(userId).enabled; 311 } 312 getLastDisabledAppCaller(int userId)313 String getLastDisabledAppCaller(int userId) { 314 return readUserState(userId).lastDisableAppCaller; 315 } 316 setInstalled(boolean inst, int userId)317 void setInstalled(boolean inst, int userId) { 318 modifyUserState(userId).installed = inst; 319 } 320 getInstalled(int userId)321 boolean getInstalled(int userId) { 322 return readUserState(userId).installed; 323 } 324 getInstallReason(int userId)325 int getInstallReason(int userId) { 326 return readUserState(userId).installReason; 327 } 328 setInstallReason(int installReason, int userId)329 void setInstallReason(int installReason, int userId) { 330 modifyUserState(userId).installReason = installReason; 331 } 332 setOverlayPaths(List<String> overlayPaths, int userId)333 void setOverlayPaths(List<String> overlayPaths, int userId) { 334 modifyUserState(userId).overlayPaths = overlayPaths == null ? null : 335 overlayPaths.toArray(new String[overlayPaths.size()]); 336 } 337 getOverlayPaths(int userId)338 String[] getOverlayPaths(int userId) { 339 return readUserState(userId).overlayPaths; 340 } 341 342 /** Only use for testing. Do NOT use in production code. */ 343 @VisibleForTesting getUserState()344 SparseArray<PackageUserState> getUserState() { 345 return userState; 346 } 347 isAnyInstalled(int[] users)348 boolean isAnyInstalled(int[] users) { 349 for (int user: users) { 350 if (readUserState(user).installed) { 351 return true; 352 } 353 } 354 return false; 355 } 356 queryInstalledUsers(int[] users, boolean installed)357 int[] queryInstalledUsers(int[] users, boolean installed) { 358 int num = 0; 359 for (int user : users) { 360 if (getInstalled(user) == installed) { 361 num++; 362 } 363 } 364 int[] res = new int[num]; 365 num = 0; 366 for (int user : users) { 367 if (getInstalled(user) == installed) { 368 res[num] = user; 369 num++; 370 } 371 } 372 return res; 373 } 374 getCeDataInode(int userId)375 long getCeDataInode(int userId) { 376 return readUserState(userId).ceDataInode; 377 } 378 setCeDataInode(long ceDataInode, int userId)379 void setCeDataInode(long ceDataInode, int userId) { 380 modifyUserState(userId).ceDataInode = ceDataInode; 381 } 382 getStopped(int userId)383 boolean getStopped(int userId) { 384 return readUserState(userId).stopped; 385 } 386 setStopped(boolean stop, int userId)387 void setStopped(boolean stop, int userId) { 388 modifyUserState(userId).stopped = stop; 389 } 390 getNotLaunched(int userId)391 boolean getNotLaunched(int userId) { 392 return readUserState(userId).notLaunched; 393 } 394 setNotLaunched(boolean stop, int userId)395 void setNotLaunched(boolean stop, int userId) { 396 modifyUserState(userId).notLaunched = stop; 397 } 398 getHidden(int userId)399 boolean getHidden(int userId) { 400 return readUserState(userId).hidden; 401 } 402 setHidden(boolean hidden, int userId)403 void setHidden(boolean hidden, int userId) { 404 modifyUserState(userId).hidden = hidden; 405 } 406 getSuspended(int userId)407 boolean getSuspended(int userId) { 408 return readUserState(userId).suspended; 409 } 410 setSuspended(boolean suspended, int userId)411 void setSuspended(boolean suspended, int userId) { 412 modifyUserState(userId).suspended = suspended; 413 } 414 getInstantApp(int userId)415 boolean getInstantApp(int userId) { 416 return readUserState(userId).instantApp; 417 } 418 setInstantApp(boolean instantApp, int userId)419 void setInstantApp(boolean instantApp, int userId) { 420 modifyUserState(userId).instantApp = instantApp; 421 } 422 getVirtulalPreload(int userId)423 boolean getVirtulalPreload(int userId) { 424 return readUserState(userId).virtualPreload; 425 } 426 setVirtualPreload(boolean virtualPreload, int userId)427 void setVirtualPreload(boolean virtualPreload, int userId) { 428 modifyUserState(userId).virtualPreload = virtualPreload; 429 } 430 setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp, boolean virtualPreload, String lastDisableAppCaller, ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, int domainVerifState, int linkGeneration, int installReason)431 void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, 432 boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp, 433 boolean virtualPreload, String lastDisableAppCaller, 434 ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, 435 int domainVerifState, int linkGeneration, int installReason) { 436 PackageUserState state = modifyUserState(userId); 437 state.ceDataInode = ceDataInode; 438 state.enabled = enabled; 439 state.installed = installed; 440 state.stopped = stopped; 441 state.notLaunched = notLaunched; 442 state.hidden = hidden; 443 state.suspended = suspended; 444 state.lastDisableAppCaller = lastDisableAppCaller; 445 state.enabledComponents = enabledComponents; 446 state.disabledComponents = disabledComponents; 447 state.domainVerificationStatus = domainVerifState; 448 state.appLinkGeneration = linkGeneration; 449 state.installReason = installReason; 450 state.instantApp = instantApp; 451 state.virtualPreload = virtualPreload; 452 } 453 getEnabledComponents(int userId)454 ArraySet<String> getEnabledComponents(int userId) { 455 return readUserState(userId).enabledComponents; 456 } 457 getDisabledComponents(int userId)458 ArraySet<String> getDisabledComponents(int userId) { 459 return readUserState(userId).disabledComponents; 460 } 461 setEnabledComponents(ArraySet<String> components, int userId)462 void setEnabledComponents(ArraySet<String> components, int userId) { 463 modifyUserState(userId).enabledComponents = components; 464 } 465 setDisabledComponents(ArraySet<String> components, int userId)466 void setDisabledComponents(ArraySet<String> components, int userId) { 467 modifyUserState(userId).disabledComponents = components; 468 } 469 setEnabledComponentsCopy(ArraySet<String> components, int userId)470 void setEnabledComponentsCopy(ArraySet<String> components, int userId) { 471 modifyUserState(userId).enabledComponents = components != null 472 ? new ArraySet<String>(components) : null; 473 } 474 setDisabledComponentsCopy(ArraySet<String> components, int userId)475 void setDisabledComponentsCopy(ArraySet<String> components, int userId) { 476 modifyUserState(userId).disabledComponents = components != null 477 ? new ArraySet<String>(components) : null; 478 } 479 modifyUserStateComponents(int userId, boolean disabled, boolean enabled)480 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 481 PackageUserState state = modifyUserState(userId); 482 if (disabled && state.disabledComponents == null) { 483 state.disabledComponents = new ArraySet<String>(1); 484 } 485 if (enabled && state.enabledComponents == null) { 486 state.enabledComponents = new ArraySet<String>(1); 487 } 488 return state; 489 } 490 addDisabledComponent(String componentClassName, int userId)491 void addDisabledComponent(String componentClassName, int userId) { 492 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 493 } 494 addEnabledComponent(String componentClassName, int userId)495 void addEnabledComponent(String componentClassName, int userId) { 496 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 497 } 498 enableComponentLPw(String componentClassName, int userId)499 boolean enableComponentLPw(String componentClassName, int userId) { 500 PackageUserState state = modifyUserStateComponents(userId, false, true); 501 boolean changed = state.disabledComponents != null 502 ? state.disabledComponents.remove(componentClassName) : false; 503 changed |= state.enabledComponents.add(componentClassName); 504 return changed; 505 } 506 disableComponentLPw(String componentClassName, int userId)507 boolean disableComponentLPw(String componentClassName, int userId) { 508 PackageUserState state = modifyUserStateComponents(userId, true, false); 509 boolean changed = state.enabledComponents != null 510 ? state.enabledComponents.remove(componentClassName) : false; 511 changed |= state.disabledComponents.add(componentClassName); 512 return changed; 513 } 514 restoreComponentLPw(String componentClassName, int userId)515 boolean restoreComponentLPw(String componentClassName, int userId) { 516 PackageUserState state = modifyUserStateComponents(userId, true, true); 517 boolean changed = state.disabledComponents != null 518 ? state.disabledComponents.remove(componentClassName) : false; 519 changed |= state.enabledComponents != null 520 ? state.enabledComponents.remove(componentClassName) : false; 521 return changed; 522 } 523 getCurrentEnabledStateLPr(String componentName, int userId)524 int getCurrentEnabledStateLPr(String componentName, int userId) { 525 PackageUserState state = readUserState(userId); 526 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 527 return COMPONENT_ENABLED_STATE_ENABLED; 528 } else if (state.disabledComponents != null 529 && state.disabledComponents.contains(componentName)) { 530 return COMPONENT_ENABLED_STATE_DISABLED; 531 } else { 532 return COMPONENT_ENABLED_STATE_DEFAULT; 533 } 534 } 535 removeUser(int userId)536 void removeUser(int userId) { 537 userState.delete(userId); 538 } 539 getNotInstalledUserIds()540 public int[] getNotInstalledUserIds() { 541 int count = 0; 542 int userStateCount = userState.size(); 543 for (int i = 0; i < userStateCount; i++) { 544 if (userState.valueAt(i).installed == false) { 545 count++; 546 } 547 } 548 if (count == 0) return EMPTY_INT_ARRAY; 549 int[] excludedUserIds = new int[count]; 550 int idx = 0; 551 for (int i = 0; i < userStateCount; i++) { 552 if (userState.valueAt(i).installed == false) { 553 excludedUserIds[idx++] = userState.keyAt(i); 554 } 555 } 556 return excludedUserIds; 557 } 558 getIntentFilterVerificationInfo()559 IntentFilterVerificationInfo getIntentFilterVerificationInfo() { 560 return verificationInfo; 561 } 562 setIntentFilterVerificationInfo(IntentFilterVerificationInfo info)563 void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) { 564 verificationInfo = info; 565 } 566 567 // Returns a packed value as a long: 568 // 569 // high 'int'-sized word: link status: undefined/ask/never/always. 570 // low 'int'-sized word: relative priority among 'always' results. getDomainVerificationStatusForUser(int userId)571 long getDomainVerificationStatusForUser(int userId) { 572 PackageUserState state = readUserState(userId); 573 long result = (long) state.appLinkGeneration; 574 result |= ((long) state.domainVerificationStatus) << 32; 575 return result; 576 } 577 setDomainVerificationStatusForUser(final int status, int generation, int userId)578 void setDomainVerificationStatusForUser(final int status, int generation, int userId) { 579 PackageUserState state = modifyUserState(userId); 580 state.domainVerificationStatus = status; 581 if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 582 state.appLinkGeneration = generation; 583 } 584 } 585 clearDomainVerificationStatusForUser(int userId)586 void clearDomainVerificationStatusForUser(int userId) { 587 modifyUserState(userId).domainVerificationStatus = 588 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 589 } 590 writeUsersInfoToProto(ProtoOutputStream proto, long fieldId)591 protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) { 592 int count = userState.size(); 593 for (int i = 0; i < count; i++) { 594 final long userToken = proto.start(fieldId); 595 final int userId = userState.keyAt(i); 596 final PackageUserState state = userState.valueAt(i); 597 proto.write(PackageProto.UserInfoProto.ID, userId); 598 final int installType; 599 if (state.instantApp) { 600 installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL; 601 } else if (state.installed) { 602 installType = PackageProto.UserInfoProto.FULL_APP_INSTALL; 603 } else { 604 installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER; 605 } 606 proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType); 607 proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden); 608 proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended); 609 proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped); 610 proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched); 611 proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled); 612 proto.write( 613 PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER, 614 state.lastDisableAppCaller); 615 proto.end(userToken); 616 } 617 } 618 } 619