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 import android.text.TextUtils; 26 27 import com.android.internal.util.CollectionUtils; 28 import com.android.internal.util.DataClass; 29 import com.android.server.pm.PackageSetting; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** 35 * For use by {@link PackageSetting} to maintain functionality that used to exist in PackageParser. 36 * 37 * It is assumed that anything inside the package was not cached or written to disk, so none of 38 * these fields are either. They must be set on every boot from other state on the device. 39 * 40 * These fields are also not copied into any cloned PackageSetting, to preserve the old behavior 41 * where they would be lost implicitly by re-generating the package object. 42 * @hide 43 */ 44 @DataClass(genSetters = true, genConstructor = false, genBuilder = false) 45 @DataClass.Suppress({"setLastPackageUsageTimeInMills", "setPackageSetting", "setUsesLibraryInfos"}) 46 public class PackageStateUnserialized { 47 48 private boolean hiddenUntilInstalled; 49 50 @NonNull 51 private List<SharedLibraryWrapper> usesLibraryInfos = emptyList(); 52 53 @NonNull 54 private List<String> usesLibraryFiles = emptyList(); 55 56 private boolean updatedSystemApp; 57 private boolean apkInUpdatedApex; 58 59 @NonNull 60 private volatile long[] lastPackageUsageTimeInMills; 61 62 @Nullable 63 private String overrideSeInfo; 64 65 @NonNull 66 private String seInfo; 67 68 // TODO: Remove in favor of finer grained change notification 69 @NonNull 70 private final PackageSetting mPackageSetting; 71 72 @Nullable 73 private String mApexModuleName; 74 PackageStateUnserialized(@onNull PackageSetting packageSetting)75 public PackageStateUnserialized(@NonNull PackageSetting packageSetting) { 76 mPackageSetting = packageSetting; 77 } 78 79 @NonNull addUsesLibraryInfo(@onNull SharedLibraryWrapper value)80 public PackageStateUnserialized addUsesLibraryInfo(@NonNull SharedLibraryWrapper value) { 81 usesLibraryInfos = CollectionUtils.add(usesLibraryInfos, value); 82 return this; 83 } 84 85 @NonNull addUsesLibraryFile(@onNull String value)86 public PackageStateUnserialized addUsesLibraryFile(@NonNull String value) { 87 usesLibraryFiles = CollectionUtils.add(usesLibraryFiles, value); 88 return this; 89 } 90 lazyInitLastPackageUsageTimeInMills()91 private long[] lazyInitLastPackageUsageTimeInMills() { 92 return new long[PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT]; 93 } 94 setLastPackageUsageTimeInMills(int reason, long time)95 public PackageStateUnserialized setLastPackageUsageTimeInMills(int reason, long time) { 96 if (reason < 0) { 97 return this; 98 } 99 if (reason >= PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT) { 100 return this; 101 } 102 getLastPackageUsageTimeInMills()[reason] = time; 103 // TODO(b/236180425): This method does not notify snapshot changes because it's called too 104 // frequently, causing too many re-takes. This should be moved to a separate data structure 105 // or merged with the general UsageStats to avoid tracking heavily mutated data in the 106 // package data snapshot. 107 return this; 108 } 109 getLatestPackageUseTimeInMills()110 public long getLatestPackageUseTimeInMills() { 111 long latestUse = 0L; 112 for (long use : getLastPackageUsageTimeInMills()) { 113 latestUse = Math.max(latestUse, use); 114 } 115 return latestUse; 116 } 117 getLatestForegroundPackageUseTimeInMills()118 public long getLatestForegroundPackageUseTimeInMills() { 119 int[] foregroundReasons = { 120 PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY, 121 PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE 122 }; 123 124 long latestUse = 0L; 125 for (int reason : foregroundReasons) { 126 latestUse = Math.max(latestUse, getLastPackageUsageTimeInMills()[reason]); 127 } 128 return latestUse; 129 } 130 updateFrom(PackageStateUnserialized other)131 public void updateFrom(PackageStateUnserialized other) { 132 this.hiddenUntilInstalled = other.hiddenUntilInstalled; 133 134 if (!other.usesLibraryInfos.isEmpty()) { 135 this.usesLibraryInfos = new ArrayList<>(other.usesLibraryInfos); 136 } 137 138 if (!other.usesLibraryFiles.isEmpty()) { 139 this.usesLibraryFiles = new ArrayList<>(other.usesLibraryFiles); 140 } 141 142 this.updatedSystemApp = other.updatedSystemApp; 143 this.apkInUpdatedApex = other.apkInUpdatedApex; 144 this.lastPackageUsageTimeInMills = other.lastPackageUsageTimeInMills; 145 this.overrideSeInfo = other.overrideSeInfo; 146 this.seInfo = other.seInfo; 147 this.mApexModuleName = other.mApexModuleName; 148 mPackageSetting.onChanged(); 149 } 150 getNonNativeUsesLibraryInfos()151 public @NonNull List<SharedLibraryInfo> getNonNativeUsesLibraryInfos() { 152 var list = new ArrayList<SharedLibraryInfo>(); 153 usesLibraryInfos = getUsesLibraryInfos(); 154 for (int index = 0; index < usesLibraryInfos.size(); index++) { 155 var library = usesLibraryInfos.get(index); 156 if (!library.isNative()) { 157 list.add(library.getInfo()); 158 } 159 160 } 161 return list; 162 } 163 setHiddenUntilInstalled(boolean value)164 public PackageStateUnserialized setHiddenUntilInstalled(boolean value) { 165 hiddenUntilInstalled = value; 166 mPackageSetting.onChanged(); 167 return this; 168 } 169 setUsesLibraryInfos(@onNull List<SharedLibraryInfo> value)170 public PackageStateUnserialized setUsesLibraryInfos(@NonNull List<SharedLibraryInfo> value) { 171 var list = new ArrayList<SharedLibraryWrapper>(); 172 for (int index = 0; index < value.size(); index++) { 173 list.add(new SharedLibraryWrapper(value.get(index))); 174 } 175 usesLibraryInfos = list; 176 mPackageSetting.onChanged(); 177 return this; 178 } 179 setUsesLibraryFiles(@onNull List<String> value)180 public PackageStateUnserialized setUsesLibraryFiles(@NonNull List<String> value) { 181 usesLibraryFiles = value; 182 mPackageSetting.onChanged(); 183 return this; 184 } 185 setUpdatedSystemApp(boolean value)186 public PackageStateUnserialized setUpdatedSystemApp(boolean value) { 187 updatedSystemApp = value; 188 mPackageSetting.onChanged(); 189 return this; 190 } 191 setApkInUpdatedApex(boolean value)192 public PackageStateUnserialized setApkInUpdatedApex(boolean value) { 193 apkInUpdatedApex = value; 194 mPackageSetting.onChanged(); 195 return this; 196 } 197 setLastPackageUsageTimeInMills(@onNull long... value)198 public PackageStateUnserialized setLastPackageUsageTimeInMills(@NonNull long... value) { 199 lastPackageUsageTimeInMills = value; 200 mPackageSetting.onChanged(); 201 return this; 202 } 203 setOverrideSeInfo(@ullable String value)204 public PackageStateUnserialized setOverrideSeInfo(@Nullable String value) { 205 overrideSeInfo = value; 206 mPackageSetting.onChanged(); 207 return this; 208 } 209 210 @NonNull setSeInfo(@onNull String value)211 public PackageStateUnserialized setSeInfo(@NonNull String value) { 212 seInfo = TextUtils.safeIntern(value); 213 mPackageSetting.onChanged(); 214 return this; 215 } 216 217 @NonNull setApexModuleName(@onNull String value)218 public PackageStateUnserialized setApexModuleName(@NonNull String value) { 219 mApexModuleName = value; 220 mPackageSetting.onChanged(); 221 return this; 222 } 223 224 225 226 // Code below generated by codegen v1.0.23. 227 // 228 // DO NOT MODIFY! 229 // CHECKSTYLE:OFF Generated code 230 // 231 // To regenerate run: 232 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java 233 // 234 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 235 // Settings > Editor > Code Style > Formatter Control 236 //@formatter:off 237 238 239 @DataClass.Generated.Member isHiddenUntilInstalled()240 public boolean isHiddenUntilInstalled() { 241 return hiddenUntilInstalled; 242 } 243 244 @DataClass.Generated.Member getUsesLibraryInfos()245 public @NonNull List<SharedLibraryWrapper> getUsesLibraryInfos() { 246 return usesLibraryInfos; 247 } 248 249 @DataClass.Generated.Member getUsesLibraryFiles()250 public @NonNull List<String> getUsesLibraryFiles() { 251 return usesLibraryFiles; 252 } 253 254 @DataClass.Generated.Member isUpdatedSystemApp()255 public boolean isUpdatedSystemApp() { 256 return updatedSystemApp; 257 } 258 259 @DataClass.Generated.Member isApkInUpdatedApex()260 public boolean isApkInUpdatedApex() { 261 return apkInUpdatedApex; 262 } 263 264 @DataClass.Generated.Member getLastPackageUsageTimeInMills()265 public @NonNull long[] getLastPackageUsageTimeInMills() { 266 long[] _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills; 267 if (_lastPackageUsageTimeInMills == null) { 268 synchronized(this) { 269 _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills; 270 if (_lastPackageUsageTimeInMills == null) { 271 _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills = lazyInitLastPackageUsageTimeInMills(); 272 } 273 } 274 } 275 return _lastPackageUsageTimeInMills; 276 } 277 278 @DataClass.Generated.Member getOverrideSeInfo()279 public @Nullable String getOverrideSeInfo() { 280 return overrideSeInfo; 281 } 282 283 @DataClass.Generated.Member getSeInfo()284 public @NonNull String getSeInfo() { 285 return seInfo; 286 } 287 288 @DataClass.Generated.Member getPackageSetting()289 public @NonNull PackageSetting getPackageSetting() { 290 return mPackageSetting; 291 } 292 293 @DataClass.Generated.Member getApexModuleName()294 public @Nullable String getApexModuleName() { 295 return mApexModuleName; 296 } 297 298 @DataClass.Generated( 299 time = 1671483772254L, 300 codegenVersion = "1.0.23", 301 sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java", 302 inputSignatures = "private boolean hiddenUntilInstalled\nprivate @android.annotation.NonNull java.util.List<com.android.server.pm.pkg.SharedLibraryWrapper> usesLibraryInfos\nprivate @android.annotation.NonNull java.util.List<java.lang.String> usesLibraryFiles\nprivate boolean updatedSystemApp\nprivate boolean apkInUpdatedApex\nprivate volatile @android.annotation.NonNull long[] lastPackageUsageTimeInMills\nprivate @android.annotation.Nullable java.lang.String overrideSeInfo\nprivate @android.annotation.NonNull java.lang.String seInfo\nprivate final @android.annotation.NonNull com.android.server.pm.PackageSetting mPackageSetting\nprivate @android.annotation.Nullable java.lang.String mApexModuleName\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized addUsesLibraryInfo(com.android.server.pm.pkg.SharedLibraryWrapper)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized addUsesLibraryFile(java.lang.String)\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 setApkInUpdatedApex(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(long)\npublic com.android.server.pm.pkg.PackageStateUnserialized setOverrideSeInfo(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized setSeInfo(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized setApexModuleName(java.lang.String)\nclass PackageStateUnserialized extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genConstructor=false, genBuilder=false)") 303 @Deprecated __metadata()304 private void __metadata() {} 305 306 307 //@formatter:on 308 // End of generated code 309 310 } 311