1 /* 2 * Copyright (C) 2020 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.pkg; 18 19 import static java.util.Collections.emptyList; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.content.pm.PackageManager; 24 import android.content.pm.SharedLibraryInfo; 25 26 import com.android.internal.util.DataClass; 27 import com.android.server.pm.PackageSetting; 28 29 import java.util.ArrayList; 30 import java.util.List; 31 import java.util.stream.Collectors; 32 33 /** 34 * For use by {@link PackageSetting} to maintain functionality that used to exist in PackageParser. 35 * 36 * It is assumed that anything inside the package was not cached or written to disk, so none of 37 * these fields are either. They must be set on every boot from other state on the device. 38 * 39 * These fields are also not copied into any cloned PackageSetting, to preserve the old behavior 40 * where they would be lost implicitly by re-generating the package object. 41 */ 42 @DataClass(genSetters = true, genConstructor = false, genBuilder = false) 43 @DataClass.Suppress({"setLastPackageUsageTimeInMills", "setPackageSetting"}) 44 public class PackageStateUnserialized { 45 46 private boolean hiddenUntilInstalled; 47 48 @NonNull 49 private List<SharedLibraryInfo> usesLibraryInfos = emptyList(); 50 51 @NonNull 52 private List<String> usesLibraryFiles = emptyList(); 53 54 private boolean updatedSystemApp; 55 56 @NonNull 57 private volatile long[] lastPackageUsageTimeInMills; 58 59 @Nullable 60 private String overrideSeInfo; 61 62 // TODO: Remove in favor of finer grained change notification 63 @NonNull 64 private final PackageSetting mPackageSetting; 65 PackageStateUnserialized(@onNull PackageSetting packageSetting)66 public PackageStateUnserialized(@NonNull PackageSetting packageSetting) { 67 mPackageSetting = packageSetting; 68 } 69 lazyInitLastPackageUsageTimeInMills()70 private long[] lazyInitLastPackageUsageTimeInMills() { 71 return new long[PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT]; 72 } 73 setLastPackageUsageTimeInMills(int reason, long time)74 public PackageStateUnserialized setLastPackageUsageTimeInMills(int reason, long time) { 75 if (reason < 0) { 76 return this; 77 } 78 if (reason >= PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT) { 79 return this; 80 } 81 getLastPackageUsageTimeInMills()[reason] = time; 82 // TODO(b/236180425): This method does not notify snapshot changes because it's called too 83 // frequently, causing too many re-takes. This should be moved to a separate data structure 84 // or merged with the general UsageStats to avoid tracking heavily mutated data in the 85 // package data snapshot. 86 return this; 87 } 88 getLatestPackageUseTimeInMills()89 public long getLatestPackageUseTimeInMills() { 90 long latestUse = 0L; 91 for (long use : getLastPackageUsageTimeInMills()) { 92 latestUse = Math.max(latestUse, use); 93 } 94 return latestUse; 95 } 96 getLatestForegroundPackageUseTimeInMills()97 public long getLatestForegroundPackageUseTimeInMills() { 98 int[] foregroundReasons = { 99 PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY, 100 PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE 101 }; 102 103 long latestUse = 0L; 104 for (int reason : foregroundReasons) { 105 latestUse = Math.max(latestUse, getLastPackageUsageTimeInMills()[reason]); 106 } 107 return latestUse; 108 } 109 updateFrom(PackageStateUnserialized other)110 public void updateFrom(PackageStateUnserialized other) { 111 this.hiddenUntilInstalled = other.hiddenUntilInstalled; 112 113 if (!other.usesLibraryInfos.isEmpty()) { 114 this.usesLibraryInfos = new ArrayList<>(other.usesLibraryInfos); 115 } 116 117 if (!other.usesLibraryFiles.isEmpty()) { 118 this.usesLibraryFiles = new ArrayList<>(other.usesLibraryFiles); 119 } 120 121 this.updatedSystemApp = other.updatedSystemApp; 122 this.lastPackageUsageTimeInMills = other.lastPackageUsageTimeInMills; 123 this.overrideSeInfo = other.overrideSeInfo; 124 mPackageSetting.onChanged(); 125 } 126 getNonNativeUsesLibraryInfos()127 public @NonNull List<SharedLibraryInfo> getNonNativeUsesLibraryInfos() { 128 return getUsesLibraryInfos().stream() 129 .filter((l) -> !l.isNative()).collect(Collectors.toList()); 130 } 131 setHiddenUntilInstalled(boolean value)132 public PackageStateUnserialized setHiddenUntilInstalled(boolean value) { 133 hiddenUntilInstalled = value; 134 mPackageSetting.onChanged(); 135 return this; 136 } 137 setUsesLibraryInfos(@onNull List<SharedLibraryInfo> value)138 public PackageStateUnserialized setUsesLibraryInfos(@NonNull List<SharedLibraryInfo> value) { 139 usesLibraryInfos = value; 140 mPackageSetting.onChanged(); 141 return this; 142 } 143 setUsesLibraryFiles(@onNull List<String> value)144 public PackageStateUnserialized setUsesLibraryFiles(@NonNull List<String> value) { 145 usesLibraryFiles = value; 146 mPackageSetting.onChanged(); 147 return this; 148 } 149 setUpdatedSystemApp(boolean value)150 public PackageStateUnserialized setUpdatedSystemApp(boolean value) { 151 updatedSystemApp = value; 152 mPackageSetting.onChanged(); 153 return this; 154 } 155 setLastPackageUsageTimeInMills(@onNull long... value)156 public PackageStateUnserialized setLastPackageUsageTimeInMills(@NonNull long... value) { 157 lastPackageUsageTimeInMills = value; 158 mPackageSetting.onChanged(); 159 return this; 160 } 161 setOverrideSeInfo(@ullable String value)162 public PackageStateUnserialized setOverrideSeInfo(@Nullable String value) { 163 overrideSeInfo = value; 164 mPackageSetting.onChanged(); 165 return this; 166 } 167 168 169 170 // Code below generated by codegen v1.0.23. 171 // 172 // DO NOT MODIFY! 173 // CHECKSTYLE:OFF Generated code 174 // 175 // To regenerate run: 176 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java 177 // 178 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 179 // Settings > Editor > Code Style > Formatter Control 180 //@formatter:off 181 182 183 @DataClass.Generated.Member isHiddenUntilInstalled()184 public boolean isHiddenUntilInstalled() { 185 return hiddenUntilInstalled; 186 } 187 188 @DataClass.Generated.Member getUsesLibraryInfos()189 public @NonNull List<SharedLibraryInfo> getUsesLibraryInfos() { 190 return usesLibraryInfos; 191 } 192 193 @DataClass.Generated.Member getUsesLibraryFiles()194 public @NonNull List<String> getUsesLibraryFiles() { 195 return usesLibraryFiles; 196 } 197 198 @DataClass.Generated.Member isUpdatedSystemApp()199 public boolean isUpdatedSystemApp() { 200 return updatedSystemApp; 201 } 202 203 @DataClass.Generated.Member getLastPackageUsageTimeInMills()204 public @NonNull long[] getLastPackageUsageTimeInMills() { 205 long[] _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills; 206 if (_lastPackageUsageTimeInMills == null) { 207 synchronized(this) { 208 _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills; 209 if (_lastPackageUsageTimeInMills == null) { 210 _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills = lazyInitLastPackageUsageTimeInMills(); 211 } 212 } 213 } 214 return _lastPackageUsageTimeInMills; 215 } 216 217 @DataClass.Generated.Member getOverrideSeInfo()218 public @Nullable String getOverrideSeInfo() { 219 return overrideSeInfo; 220 } 221 222 @DataClass.Generated.Member getPackageSetting()223 public @NonNull PackageSetting getPackageSetting() { 224 return mPackageSetting; 225 } 226 227 @DataClass.Generated( 228 time = 1642554781099L, 229 codegenVersion = "1.0.23", 230 sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java", 231 inputSignatures = "private boolean hiddenUntilInstalled\nprivate @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> usesLibraryInfos\nprivate @android.annotation.NonNull java.util.List<java.lang.String> usesLibraryFiles\nprivate boolean updatedSystemApp\nprivate volatile @android.annotation.NonNull long[] lastPackageUsageTimeInMills\nprivate @android.annotation.Nullable java.lang.String overrideSeInfo\nprivate @android.annotation.NonNull com.android.server.pm.PackageSetting mPackageSetting\nprivate long[] lazyInitLastPackageUsageTimeInMills()\npublic com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(int,long)\npublic long getLatestPackageUseTimeInMills()\npublic long getLatestForegroundPackageUseTimeInMills()\npublic void updateFrom(com.android.server.pm.pkg.PackageStateUnserialized)\npublic @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> getNonNativeUsesLibraryInfos()\npublic com.android.server.pm.pkg.PackageStateUnserialized setHiddenUntilInstalled(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryInfos(java.util.List<android.content.pm.SharedLibraryInfo>)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryFiles(java.util.List<java.lang.String>)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUpdatedSystemApp(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(long)\npublic com.android.server.pm.pkg.PackageStateUnserialized setOverrideSeInfo(java.lang.String)\nclass PackageStateUnserialized extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genConstructor=false, genBuilder=false)") 232 @Deprecated __metadata()233 private void __metadata() {} 234 235 236 //@formatter:on 237 // End of generated code 238 239 } 240