• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.parsing;
18 
19 import android.annotation.CheckResult;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.UserIdInt;
23 import android.content.pm.ActivityInfo;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.Attribution;
26 import android.content.pm.ComponentInfo;
27 import android.content.pm.ConfigurationInfo;
28 import android.content.pm.FallbackCategoryProvider;
29 import android.content.pm.FeatureGroupInfo;
30 import android.content.pm.FeatureInfo;
31 import android.content.pm.Flags;
32 import android.content.pm.InstrumentationInfo;
33 import android.content.pm.PackageInfo;
34 import android.content.pm.PackageItemInfo;
35 import android.content.pm.PackageManager;
36 import android.content.pm.PathPermission;
37 import android.content.pm.PermissionGroupInfo;
38 import android.content.pm.PermissionInfo;
39 import android.content.pm.ProcessInfo;
40 import android.content.pm.ProviderInfo;
41 import android.content.pm.ServiceInfo;
42 import android.content.pm.SharedLibraryInfo;
43 import android.content.pm.Signature;
44 import android.content.pm.SigningDetails;
45 import android.content.pm.SigningInfo;
46 import android.content.pm.overlay.OverlayPaths;
47 import android.os.Environment;
48 import android.os.PatternMatcher;
49 import android.os.UserHandle;
50 import android.util.ArrayMap;
51 import android.util.ArraySet;
52 import android.util.Pair;
53 import android.util.Slog;
54 
55 import com.android.internal.annotations.VisibleForTesting;
56 import com.android.internal.pm.parsing.pkg.AndroidPackageLegacyUtils;
57 import com.android.internal.pm.parsing.pkg.PackageImpl;
58 import com.android.internal.pm.pkg.component.ComponentParseUtils;
59 import com.android.internal.pm.pkg.component.ParsedActivity;
60 import com.android.internal.pm.pkg.component.ParsedAttribution;
61 import com.android.internal.pm.pkg.component.ParsedComponent;
62 import com.android.internal.pm.pkg.component.ParsedInstrumentation;
63 import com.android.internal.pm.pkg.component.ParsedMainComponent;
64 import com.android.internal.pm.pkg.component.ParsedPermission;
65 import com.android.internal.pm.pkg.component.ParsedPermissionGroup;
66 import com.android.internal.pm.pkg.component.ParsedProcess;
67 import com.android.internal.pm.pkg.component.ParsedProvider;
68 import com.android.internal.pm.pkg.component.ParsedService;
69 import com.android.internal.pm.pkg.component.ParsedUsesPermission;
70 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
71 import com.android.internal.pm.pkg.parsing.ParsingUtils;
72 import com.android.internal.util.ArrayUtils;
73 import com.android.server.SystemConfig;
74 import com.android.server.pm.PackageArchiver;
75 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
76 import com.android.server.pm.pkg.AndroidPackage;
77 import com.android.server.pm.pkg.PackageStateInternal;
78 import com.android.server.pm.pkg.PackageStateUnserialized;
79 import com.android.server.pm.pkg.PackageUserState;
80 import com.android.server.pm.pkg.PackageUserStateInternal;
81 import com.android.server.pm.pkg.PackageUserStateUtils;
82 import com.android.server.pm.pkg.SELinuxUtil;
83 
84 import java.io.File;
85 import java.util.ArrayList;
86 import java.util.List;
87 import java.util.Map;
88 import java.util.Set;
89 
90 
91 /**
92  * Methods that use a {@link PackageStateInternal} use it to override information provided from the
93  * raw package, or to provide information that would otherwise be missing. Null can be passed if
94  * none of the state values should be applied.
95  *
96  * @hide
97  **/
98 public class PackageInfoUtils {
99     private static final String TAG = ParsingUtils.TAG;
100 
101     private static final String SYSTEM_DATA_PATH =
102             Environment.getDataDirectoryPath() + File.separator + "system";
103 
104     /**
105      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
106      */
107     @Nullable
generate(AndroidPackage pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions, PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)108     public static PackageInfo generate(AndroidPackage pkg, int[] gids,
109             @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
110             long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions,
111             PackageUserStateInternal state, @UserIdInt int userId,
112             @NonNull PackageStateInternal pkgSetting) {
113         return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime,
114                 installedPermissions, grantedPermissions, state, userId, pkgSetting);
115     }
116 
117     /**
118      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
119      */
generateWithComponents(AndroidPackage pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions, PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)120     private static PackageInfo generateWithComponents(AndroidPackage pkg, int[] gids,
121             @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
122             long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions,
123             PackageUserStateInternal state, @UserIdInt int userId,
124             @NonNull PackageStateInternal pkgSetting) {
125         ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId,
126                 pkgSetting);
127         if (applicationInfo == null) {
128             return null;
129         }
130 
131         PackageInfo info = new PackageInfo();
132         info.packageName = pkg.getPackageName();
133         info.splitNames = pkg.getSplitNames();
134         AndroidPackageUtils.fillVersionCodes(pkg, info);
135         info.baseRevisionCode = pkg.getBaseRevisionCode();
136         info.splitRevisionCodes = pkg.getSplitRevisionCodes();
137         info.versionName = pkg.getVersionName();
138         info.sharedUserId = pkg.getSharedUserId();
139         info.sharedUserLabel = pkg.getSharedUserLabelResourceId();
140         info.applicationInfo = applicationInfo;
141         info.installLocation = pkg.getInstallLocation();
142         if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
143                 || (info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
144             info.requiredForAllUsers = pkg.isRequiredForAllUsers();
145         }
146         info.restrictedAccountType = pkg.getRestrictedAccountType();
147         info.requiredAccountType = pkg.getRequiredAccountType();
148         info.overlayTarget = pkg.getOverlayTarget();
149         info.targetOverlayableName = pkg.getOverlayTargetOverlayableName();
150         info.overlayCategory = pkg.getOverlayCategory();
151         info.overlayPriority = pkg.getOverlayPriority();
152         info.mOverlayIsStatic = pkg.isOverlayIsStatic();
153         info.compileSdkVersion = pkg.getCompileSdkVersion();
154         info.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
155         info.firstInstallTime = firstInstallTime;
156         info.lastUpdateTime = lastUpdateTime;
157         if (state.getArchiveState() != null) {
158             info.setArchiveTimeMillis(state.getArchiveState().getArchiveTimeMillis());
159         }
160         if ((flags & PackageManager.GET_GIDS) != 0) {
161             info.gids = gids;
162         }
163         if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) {
164             int size = pkg.getConfigPreferences().size();
165             if (size > 0) {
166                 info.configPreferences = new ConfigurationInfo[size];
167                 pkg.getConfigPreferences().toArray(info.configPreferences);
168             }
169             size = pkg.getRequestedFeatures().size();
170             if (size > 0) {
171                 info.reqFeatures = new FeatureInfo[size];
172                 pkg.getRequestedFeatures().toArray(info.reqFeatures);
173             }
174             size = pkg.getFeatureGroups().size();
175             if (size > 0) {
176                 info.featureGroups = new FeatureGroupInfo[size];
177                 pkg.getFeatureGroups().toArray(info.featureGroups);
178             }
179         }
180         if ((flags & PackageManager.GET_PERMISSIONS) != 0) {
181             int size = ArrayUtils.size(pkg.getPermissions());
182             if (size > 0) {
183                 info.permissions = new PermissionInfo[size];
184                 for (int i = 0; i < size; i++) {
185                     final var permission = pkg.getPermissions().get(i);
186                     final var permissionInfo = generatePermissionInfo(permission, flags);
187                     if (installedPermissions.contains(permission.getName())) {
188                         permissionInfo.flags |= PermissionInfo.FLAG_INSTALLED;
189                     }
190                     info.permissions[i] = permissionInfo;
191                 }
192             }
193             final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
194             size = usesPermissions.size();
195             if (size > 0) {
196                 info.requestedPermissions = new String[size];
197                 info.requestedPermissionsFlags = new int[size];
198                 for (int i = 0; i < size; i++) {
199                     final ParsedUsesPermission usesPermission = usesPermissions.get(i);
200                     info.requestedPermissions[i] = usesPermission.getName();
201                     // The notion of required permissions is deprecated but for compatibility.
202                     info.requestedPermissionsFlags[i] |=
203                             PackageInfo.REQUESTED_PERMISSION_REQUIRED;
204                     if (grantedPermissions != null
205                             && grantedPermissions.contains(usesPermission.getName())) {
206                         info.requestedPermissionsFlags[i] |=
207                                 PackageInfo.REQUESTED_PERMISSION_GRANTED;
208                     }
209                     if ((usesPermission.getUsesPermissionFlags()
210                             & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
211                         info.requestedPermissionsFlags[i] |=
212                                 PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
213                     }
214                     if (pkg.getImplicitPermissions().contains(info.requestedPermissions[i])) {
215                         info.requestedPermissionsFlags[i] |=
216                                 PackageInfo.REQUESTED_PERMISSION_IMPLICIT;
217                     }
218                 }
219             }
220         }
221         if ((flags & PackageManager.GET_ATTRIBUTIONS_LONG) != 0) {
222             int size = ArrayUtils.size(pkg.getAttributions());
223             if (size > 0) {
224                 info.attributions = new Attribution[size];
225                 for (int i = 0; i < size; i++) {
226                     ParsedAttribution parsedAttribution = pkg.getAttributions().get(i);
227                     if (parsedAttribution != null) {
228                         info.attributions[i] = new Attribution(parsedAttribution.getTag(),
229                                 parsedAttribution.getLabel());
230                     }
231                 }
232             }
233             if (pkg.isAttributionsUserVisible()) {
234                 info.applicationInfo.privateFlagsExt
235                         |= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
236             } else {
237                 info.applicationInfo.privateFlagsExt
238                         &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
239             }
240         } else {
241             info.applicationInfo.privateFlagsExt
242                     &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
243         }
244 
245         final SigningDetails signingDetails = pkg.getSigningDetails();
246         info.signatures = getDeprecatedSignatures(signingDetails, flags);
247 
248         // replacement for GET_SIGNATURES
249         if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
250             if (signingDetails != SigningDetails.UNKNOWN) {
251                 // only return a valid SigningInfo if there is signing information to report
252                 info.signingInfo = new SigningInfo(signingDetails);
253             } else {
254                 info.signingInfo = null;
255             }
256         }
257 
258         info.isStub = pkg.isStub();
259         info.coreApp = pkg.isCoreApp();
260         info.isApex = pkg.isApex();
261 
262         if (!pkgSetting.hasSharedUser()) {
263             // It is possible that this shared UID app has left
264             info.sharedUserId = null;
265             info.sharedUserLabel = 0;
266         }
267 
268         if ((flags & PackageManager.GET_ACTIVITIES) != 0) {
269             final int N = pkg.getActivities().size();
270             if (N > 0) {
271                 // Allow to match activities of quarantined packages.
272                 long aflags = flags | PackageManager.MATCH_QUARANTINED_COMPONENTS;
273 
274                 int num = 0;
275                 final ActivityInfo[] res = new ActivityInfo[N];
276                 for (int i = 0; i < N; i++) {
277                     final ParsedActivity a = pkg.getActivities().get(i);
278                     if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(),
279                             a.isEnabled(), a.isDirectBootAware(), a.getName(), aflags)) {
280                         if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
281                                 a.getName())) {
282                             continue;
283                         }
284                         res[num++] = generateActivityInfo(pkg, a, aflags, state,
285                                 applicationInfo, userId, pkgSetting);
286                     }
287                 }
288                 info.activities = ArrayUtils.trimToSize(res, num);
289             }
290         }
291         if ((flags & PackageManager.GET_RECEIVERS) != 0) {
292             final int size = pkg.getReceivers().size();
293             if (size > 0) {
294                 int num = 0;
295                 final ActivityInfo[] res = new ActivityInfo[size];
296                 for (int i = 0; i < size; i++) {
297                     final ParsedActivity a = pkg.getReceivers().get(i);
298                     if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(),
299                             a.isEnabled(), a.isDirectBootAware(), a.getName(), flags)) {
300                         res[num++] = generateActivityInfo(pkg, a, flags, state, applicationInfo,
301                                 userId, pkgSetting);
302                     }
303                 }
304                 info.receivers = ArrayUtils.trimToSize(res, num);
305             }
306         }
307         if ((flags & PackageManager.GET_SERVICES) != 0) {
308             final int size = pkg.getServices().size();
309             if (size > 0) {
310                 int num = 0;
311                 final ServiceInfo[] res = new ServiceInfo[size];
312                 for (int i = 0; i < size; i++) {
313                     final ParsedService s = pkg.getServices().get(i);
314                     if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(),
315                             s.isEnabled(), s.isDirectBootAware(), s.getName(), flags)) {
316                         res[num++] = generateServiceInfo(pkg, s, flags, state, applicationInfo,
317                                 userId, pkgSetting);
318                     }
319                 }
320                 info.services = ArrayUtils.trimToSize(res, num);
321             }
322         }
323         if ((flags & PackageManager.GET_PROVIDERS) != 0) {
324             final int size = pkg.getProviders().size();
325             if (size > 0) {
326                 int num = 0;
327                 final ProviderInfo[] res = new ProviderInfo[size];
328                 for (int i = 0; i < size; i++) {
329                     final ParsedProvider pr = pkg.getProviders()
330                             .get(i);
331                     if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(),
332                             pr.isEnabled(), pr.isDirectBootAware(), pr.getName(), flags)) {
333                         res[num++] = generateProviderInfo(pkg, pr, flags, state, applicationInfo,
334                                 userId, pkgSetting);
335                     }
336                 }
337                 info.providers = ArrayUtils.trimToSize(res, num);
338             }
339         }
340         if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) {
341             int N = pkg.getInstrumentations().size();
342             if (N > 0) {
343                 info.instrumentation = new InstrumentationInfo[N];
344                 for (int i = 0; i < N; i++) {
345                     info.instrumentation[i] = generateInstrumentationInfo(
346                             pkg.getInstrumentations().get(i), pkg, flags, state,
347                             userId, pkgSetting);
348                 }
349             }
350         }
351 
352         return info;
353     }
354 
355     /**
356      * Retrieve the deprecated {@link PackageInfo.signatures} field of signing certificates
357      */
getDeprecatedSignatures(SigningDetails signingDetails, long flags)358     public static Signature[] getDeprecatedSignatures(SigningDetails signingDetails, long flags) {
359         if ((flags & PackageManager.GET_SIGNATURES) == 0) {
360             return null;
361         }
362         if (signingDetails.hasPastSigningCertificates()) {
363             // Package has included signing certificate rotation information.  Return the oldest
364             // cert so that programmatic checks keep working even if unaware of key rotation.
365             Signature[] signatures = new Signature[1];
366             signatures[0] = signingDetails.getPastSigningCertificates()[0];
367             return signatures;
368         } else if (signingDetails.hasSignatures()) {
369             // otherwise keep old behavior
370             int numberOfSigs = signingDetails.getSignatures().length;
371             Signature[] signatures = new Signature[numberOfSigs];
372             System.arraycopy(signingDetails.getSignatures(), 0, signatures, 0,
373                     numberOfSigs);
374             return signatures;
375         }
376         return null;
377     }
378 
updateApplicationInfo(ApplicationInfo ai, long flags, PackageUserState state)379     private static void updateApplicationInfo(ApplicationInfo ai, long flags,
380             PackageUserState state) {
381         if ((flags & PackageManager.GET_META_DATA) == 0) {
382             ai.metaData = null;
383         }
384         if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) {
385             ai.sharedLibraryFiles = null;
386             ai.sharedLibraryInfos = null;
387         }
388 
389         // CompatibilityMode is global state.
390         if (!ParsingPackageUtils.sCompatibilityModeEnabled) {
391             ai.disableCompatibilityMode();
392         }
393 
394         ai.flags |= flag(state.isStopped(), ApplicationInfo.FLAG_STOPPED)
395                 | flag(state.isInstalled(), ApplicationInfo.FLAG_INSTALLED)
396                 | flag(state.isSuspended(), ApplicationInfo.FLAG_SUSPENDED);
397         ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT)
398                 | flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD)
399                 | flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN);
400         ai.privateFlagsExt |=
401                 flag(state.isNotLaunched(), ApplicationInfo.PRIVATE_FLAG_EXT_NOT_LAUNCHED);
402         if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
403             ai.enabled = true;
404         } else if (state.getEnabledState()
405                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
406             ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
407         } else if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
408                 || state.getEnabledState()
409                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
410             ai.enabled = false;
411         }
412         ai.enabledSetting = state.getEnabledState();
413         if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
414             ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
415         }
416         ai.seInfoUser = SELinuxUtil.getSeinfoUser(state);
417         final OverlayPaths overlayPaths = state.getAllOverlayPaths();
418         if (overlayPaths != null) {
419             ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
420             ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
421         }
422         ai.isArchived = PackageArchiver.isArchived(state);
423         if (ai.isArchived) {
424             ai.nonLocalizedLabel = state.getArchiveState().getActivityInfos().get(0).getTitle();
425         }
426         if (!state.isInstalled() && !state.dataExists()
427                 && android.content.pm.Flags.nullableDataDir()) {
428             // The data dir has been deleted
429             ai.dataDir = null;
430         }
431     }
432 
433     @Nullable
generateDelegateApplicationInfo(@ullable ApplicationInfo ai, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)434     public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai,
435             @PackageManager.ApplicationInfoFlagsBits long flags,
436             @NonNull PackageUserState state, int userId) {
437         if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) {
438             return null;
439         }
440 
441         ai = new ApplicationInfo(ai);
442         ai.initForUser(userId);
443         ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes
444                 : ai.iconRes;
445         updateApplicationInfo(ai, flags, state);
446         return ai;
447     }
448 
449     /**
450      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
451      */
452     @VisibleForTesting
453     @Nullable
generateApplicationInfo(AndroidPackage pkg, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)454     public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg,
455             @PackageManager.ApplicationInfoFlagsBits long flags,
456             @NonNull PackageUserStateInternal state, @UserIdInt int userId,
457             @NonNull PackageStateInternal pkgSetting) {
458         if (pkg == null) {
459             return null;
460         }
461 
462         if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)
463                 || !AndroidPackageUtils.isMatchForSystemOnly(pkgSetting, flags)) {
464             return null;
465         }
466 
467         // Make shallow copy so we can store the metadata/libraries safely
468         ApplicationInfo info = AndroidPackageUtils.generateAppInfoWithoutState(pkg);
469 
470         updateApplicationInfo(info, flags, state);
471 
472         initForUser(info, pkg, userId, state);
473 
474         // TODO(b/135203078): Remove PackageParser1/toAppInfoWithoutState and clean all this up
475         PackageStateUnserialized pkgState = pkgSetting.getTransientState();
476         info.hiddenUntilInstalled = pkgState.isHiddenUntilInstalled();
477         List<String> usesLibraryFiles = pkgState.getUsesLibraryFiles();
478         var usesLibraries = pkgState.getUsesLibraryInfos();
479         var usesLibraryInfos = new ArrayList<SharedLibraryInfo>();
480         for (int index = 0; index < usesLibraries.size(); index++) {
481             usesLibraryInfos.add(usesLibraries.get(index).getInfo());
482         }
483         info.sharedLibraryFiles = usesLibraryFiles.isEmpty()
484                 ? null : usesLibraryFiles.toArray(new String[0]);
485 
486 
487         if (!Flags.sdkLibIndependence()) {
488             info.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos;
489             info.optionalSharedLibraryInfos = null;
490         } else {
491             // sharedLibraryInfos contains all shared libraries that the app depends on (including
492             // the optional sdk libraries)
493             info.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos;
494             String[] libsNames = pkgSetting.getUsesSdkLibraries();
495             boolean[] libsOptional = pkgSetting.getUsesSdkLibrariesOptional();
496             List<SharedLibraryInfo> optionalSdkLibraries = null;
497             if (!ArrayUtils.isEmpty(libsOptional) && !ArrayUtils.isEmpty(libsNames)
498                     && libsNames.length == libsOptional.length) {
499                 for (SharedLibraryInfo info1 : usesLibraryInfos) {
500                     if (info1.getType() == SharedLibraryInfo.TYPE_SDK_PACKAGE) {
501                         int index = ArrayUtils.indexOf(libsNames, info1.getName());
502                         if (index >= 0 && libsOptional[index]) {
503                             if (optionalSdkLibraries == null) {
504                                 optionalSdkLibraries = new ArrayList<>();
505                             }
506                             optionalSdkLibraries.add(info1);
507                         }
508                     }
509                 }
510             }
511             info.optionalSharedLibraryInfos = optionalSdkLibraries;
512         }
513         if (info.category == ApplicationInfo.CATEGORY_UNDEFINED) {
514             info.category = pkgSetting.getCategoryOverride();
515         }
516 
517         info.seInfo = pkgSetting.getSeInfo();
518         info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi();
519         info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi();
520 
521         info.flags |= appInfoFlags(info.flags, pkgSetting);
522         info.privateFlags |= appInfoPrivateFlags(info.privateFlags, pkgSetting);
523         info.privateFlagsExt |= appInfoPrivateFlagsExt(info.privateFlagsExt, pkgSetting);
524 
525         return info;
526     }
527 
528     /**
529      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
530      */
531     @VisibleForTesting
532     @Nullable
generateActivityInfo(AndroidPackage pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)533     public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
534             @PackageManager.ComponentInfoFlagsBits long flags,
535             @NonNull PackageUserStateInternal state, @UserIdInt int userId,
536             @NonNull PackageStateInternal pkgSetting) {
537         return generateActivityInfo(pkg, a, flags, state, null, userId, pkgSetting);
538     }
539 
540     /**
541      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
542      */
543     @VisibleForTesting
544     @Nullable
generateActivityInfo(AndroidPackage pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)545     public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
546             @PackageManager.ComponentInfoFlagsBits long flags,
547             @NonNull PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo,
548             @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) {
549         if (a == null) return null;
550         if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) {
551             return null;
552         }
553         if (applicationInfo == null) {
554             applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting);
555         }
556 
557         if (applicationInfo == null) {
558             return null;
559         }
560 
561         // Make shallow copies so we can store the metadata safely
562         ActivityInfo ai = new ActivityInfo();
563         ai.targetActivity = a.getTargetActivity();
564         ai.processName = a.getProcessName();
565         ai.exported = a.isExported();
566         ai.theme = a.getTheme();
567         ai.uiOptions = a.getUiOptions();
568         ai.parentActivityName = a.getParentActivityName();
569         ai.permission = a.getPermission();
570         ai.taskAffinity = a.getTaskAffinity();
571         ai.flags = a.getFlags();
572         ai.privateFlags = a.getPrivateFlags();
573         ai.launchMode = a.getLaunchMode();
574         ai.documentLaunchMode = a.getDocumentLaunchMode();
575         ai.maxRecents = a.getMaxRecents();
576         ai.configChanges = a.getConfigChanges();
577         ai.softInputMode = a.getSoftInputMode();
578         ai.persistableMode = a.getPersistableMode();
579         ai.lockTaskLaunchMode = a.getLockTaskLaunchMode();
580         ai.screenOrientation = a.getScreenOrientation();
581         ai.resizeMode = a.getResizeMode();
582         ai.setMaxAspectRatio(a.getMaxAspectRatio());
583         ai.setMinAspectRatio(a.getMinAspectRatio());
584         ai.supportsSizeChanges = a.isSupportsSizeChanges();
585         ai.requestedVrComponent = a.getRequestedVrComponent();
586         ai.rotationAnimation = a.getRotationAnimation();
587         ai.colorMode = a.getColorMode();
588         ai.windowLayout = a.getWindowLayout();
589         ai.attributionTags = a.getAttributionTags();
590         if ((flags & PackageManager.GET_META_DATA) != 0) {
591             var metaData = a.getMetaData();
592             // Backwards compatibility, coerce to null if empty
593             ai.metaData = metaData.isEmpty() ? null : metaData;
594         } else {
595             ai.metaData = null;
596         }
597         ai.applicationInfo = applicationInfo;
598         ai.requiredDisplayCategory = a.getRequiredDisplayCategory();
599         ai.requireContentUriPermissionFromCaller = a.getRequireContentUriPermissionFromCaller();
600         ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts());
601         assignFieldsComponentInfoParsedMainComponent(ai, a, pkgSetting, userId);
602         return ai;
603     }
604 
605     @Nullable
generateDelegateActivityInfo(@ullable ActivityInfo a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)606     public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a,
607             @PackageManager.ComponentInfoFlagsBits long flags,
608             @NonNull PackageUserState state, int userId) {
609         if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) {
610             return null;
611         }
612         // This is used to return the ResolverActivity or instantAppInstallerActivity;
613         // we will just always make a copy.
614         final ActivityInfo ai = new ActivityInfo(a);
615         ai.applicationInfo =
616                 generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId);
617         return ai;
618     }
619 
620     /**
621      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
622      */
623     @Nullable
generateServiceInfo(AndroidPackage pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)624     public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s,
625             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state,
626             @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) {
627         return generateServiceInfo(pkg, s, flags, state, null, userId, pkgSetting);
628     }
629 
630     /**
631      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
632      */
633     @VisibleForTesting
634     @Nullable
generateServiceInfo(AndroidPackage pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, int userId, @NonNull PackageStateInternal pkgSetting)635     public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s,
636             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state,
637             @Nullable ApplicationInfo applicationInfo, int userId,
638             @NonNull PackageStateInternal pkgSetting) {
639         if (s == null) return null;
640         if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) {
641             return null;
642         }
643         if (applicationInfo == null) {
644             applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting);
645         }
646         if (applicationInfo == null) {
647             return null;
648         }
649 
650 
651         // Make shallow copies so we can store the metadata safely
652         ServiceInfo si = new ServiceInfo();
653         si.exported = s.isExported();
654         si.flags = s.getFlags();
655         si.permission = s.getPermission();
656         si.processName = s.getProcessName();
657         si.mForegroundServiceType = s.getForegroundServiceType();
658         si.applicationInfo = applicationInfo;
659         if ((flags & PackageManager.GET_META_DATA) != 0) {
660             var metaData = s.getMetaData();
661             // Backwards compatibility, coerce to null if empty
662             si.metaData = metaData.isEmpty() ? null : metaData;
663         }
664         assignFieldsComponentInfoParsedMainComponent(si, s, pkgSetting, userId);
665         return si;
666     }
667 
668     /**
669      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
670      */
671     @VisibleForTesting
672     @Nullable
generateProviderInfo(AndroidPackage pkg, ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @NonNull ApplicationInfo applicationInfo, int userId, @NonNull PackageStateInternal pkgSetting)673     public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p,
674             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state,
675             @NonNull ApplicationInfo applicationInfo, int userId,
676             @NonNull PackageStateInternal pkgSetting) {
677         if (p == null) return null;
678         if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) {
679             return null;
680         }
681         if (applicationInfo == null || !pkg.getPackageName().equals(applicationInfo.packageName)) {
682             Slog.wtf(TAG, "AppInfo's package name is different. Expected=" + pkg.getPackageName()
683                     + " actual=" + (applicationInfo == null ? "(null AppInfo)"
684                     : applicationInfo.packageName));
685             applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting);
686         }
687         if (applicationInfo == null) {
688             return null;
689         }
690 
691         // Make shallow copies so we can store the metadata safely
692         ProviderInfo pi = new ProviderInfo();
693         pi.exported = p.isExported();
694         pi.flags = p.getFlags();
695         pi.processName = p.getProcessName();
696         pi.authority = p.getAuthority();
697         pi.isSyncable = p.isSyncable();
698         pi.readPermission = p.getReadPermission();
699         pi.writePermission = p.getWritePermission();
700         pi.grantUriPermissions = p.isGrantUriPermissions();
701         pi.forceUriPermissions = p.isForceUriPermissions();
702         pi.multiprocess = p.isMultiProcess();
703         pi.initOrder = p.getInitOrder();
704         pi.uriPermissionPatterns = p.getUriPermissionPatterns().toArray(new PatternMatcher[0]);
705         pi.pathPermissions = p.getPathPermissions().toArray(new PathPermission[0]);
706         if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
707             pi.uriPermissionPatterns = null;
708         }
709         if ((flags & PackageManager.GET_META_DATA) != 0) {
710             var metaData = p.getMetaData();
711             // Backwards compatibility, coerce to null if empty
712             pi.metaData = metaData.isEmpty() ? null : metaData;
713         }
714         pi.applicationInfo = applicationInfo;
715         assignFieldsComponentInfoParsedMainComponent(pi, p, pkgSetting, userId);
716         return pi;
717     }
718 
719     /**
720      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
721      */
722     @Nullable
generateInstrumentationInfo(ParsedInstrumentation i, AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting)723     public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
724             AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags,
725             PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting) {
726         if (i == null) return null;
727         if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) {
728             return null;
729         }
730 
731         InstrumentationInfo info = new InstrumentationInfo();
732         info.targetPackage = i.getTargetPackage();
733         info.targetProcesses = i.getTargetProcesses();
734         info.handleProfiling = i.isHandleProfiling();
735         info.functionalTest = i.isFunctionalTest();
736 
737         info.sourceDir = pkg.getBaseApkPath();
738         info.publicSourceDir = pkg.getBaseApkPath();
739         info.splitNames = pkg.getSplitNames();
740         info.splitSourceDirs = pkg.getSplitCodePaths().length == 0 ? null : pkg.getSplitCodePaths();
741         info.splitPublicSourceDirs = pkg.getSplitCodePaths().length == 0
742                 ? null : pkg.getSplitCodePaths();
743         info.splitDependencies = pkg.getSplitDependencies().size() == 0
744                 ? null : pkg.getSplitDependencies();
745 
746         initForUser(info, pkg, userId, state);
747 
748         info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi();
749         info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi();
750         info.nativeLibraryDir = pkg.getNativeLibraryDir();
751         info.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir();
752 
753         assignFieldsPackageItemInfoParsedComponent(info, i, pkgSetting, userId);
754 
755         if ((flags & PackageManager.GET_META_DATA) == 0) {
756             info.metaData = null;
757         } else {
758             var metaData = i.getMetaData();
759             // Backwards compatibility, coerce to null if empty
760             info.metaData = metaData.isEmpty() ? null : metaData;
761         }
762 
763         return info;
764     }
765 
766     // TODO(b/135203078): Determine if permission methods need to pass in a non-null
767     //  PackageStateInternal os that checkUseInstalledOrHidden filter can apply
768     @Nullable
generatePermissionInfo(ParsedPermission p, @PackageManager.ComponentInfoFlagsBits long flags)769     public static PermissionInfo generatePermissionInfo(ParsedPermission p,
770             @PackageManager.ComponentInfoFlagsBits long flags) {
771         // TODO(b/135203078): Remove null checks and make all usages @NonNull
772         if (p == null) return null;
773 
774         PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission());
775 
776         assignFieldsPackageItemInfoParsedComponent(pi, p);
777 
778         pi.group = p.getGroup();
779         pi.requestRes = p.getRequestRes();
780         pi.protectionLevel = p.getProtectionLevel();
781         pi.descriptionRes = p.getDescriptionRes();
782         pi.flags = p.getFlags();
783         pi.knownCerts = p.getKnownCerts();
784 
785         if ((flags & PackageManager.GET_META_DATA) == 0) {
786             pi.metaData = null;
787         } else {
788             var metaData = p.getMetaData();
789             // Backwards compatibility, coerce to null if empty
790             pi.metaData = metaData.isEmpty() ? null : metaData;
791         }
792         return pi;
793     }
794 
795     @Nullable
generatePermissionGroupInfo(ParsedPermissionGroup pg, @PackageManager.ComponentInfoFlagsBits long flags)796     public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg,
797             @PackageManager.ComponentInfoFlagsBits long flags) {
798         if (pg == null) return null;
799 
800         PermissionGroupInfo pgi = new PermissionGroupInfo(
801                 pg.getRequestDetailRes(),
802                 pg.getBackgroundRequestRes(),
803                 pg.getBackgroundRequestDetailRes()
804         );
805 
806         assignFieldsPackageItemInfoParsedComponent(pgi, pg);
807         pgi.descriptionRes = pg.getDescriptionRes();
808         pgi.priority = pg.getPriority();
809         pgi.requestRes = pg.getRequestRes();
810         pgi.flags = pg.getFlags();
811 
812         if ((flags & PackageManager.GET_META_DATA) == 0) {
813             pgi.metaData = null;
814         } else {
815             var metaData = pg.getMetaData();
816             // Backwards compatibility, coerce to null if empty
817             pgi.metaData = metaData.isEmpty() ? null : metaData;
818         }
819 
820         return pgi;
821     }
822 
823     @Nullable
generateProcessInfo( Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlagsBits long flags)824     public static ArrayMap<String, ProcessInfo> generateProcessInfo(
825             Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlagsBits long flags) {
826         if (procs == null) {
827             return null;
828         }
829 
830         final int numProcs = procs.size();
831         ArrayMap<String, ProcessInfo> retProcs = new ArrayMap<>(numProcs);
832         for (String key : procs.keySet()) {
833             ParsedProcess proc = procs.get(key);
834             retProcs.put(proc.getName(),
835                     new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()),
836                             proc.getGwpAsanMode(), proc.getMemtagMode(),
837                             proc.getNativeHeapZeroInitialized(), proc.isUseEmbeddedDex()));
838         }
839         return retProcs;
840     }
841 
842     /**
843      * Returns true if the package is installed and not hidden, or if the caller explicitly wanted
844      * all uninstalled and hidden packages as well.
845      */
checkUseInstalledOrHidden(AndroidPackage pkg, @NonNull PackageStateInternal pkgSetting, PackageUserStateInternal state, @PackageManager.PackageInfoFlagsBits long flags)846     public static boolean checkUseInstalledOrHidden(AndroidPackage pkg,
847             @NonNull PackageStateInternal pkgSetting, PackageUserStateInternal state,
848             @PackageManager.PackageInfoFlagsBits long flags) {
849         // Returns false if the package is hidden system app until installed.
850         if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
851                 && !state.isInstalled()
852                 && pkgSetting.getTransientState().isHiddenUntilInstalled()) {
853             return false;
854         }
855 
856         // If available for the target user, or trying to match uninstalled packages and it's
857         // a system app.
858         return PackageUserStateUtils.isAvailable(state, flags)
859                 || (pkgSetting.isSystem() && matchUninstalledOrHidden(flags));
860     }
861 
checkUseInstalledOrHidden(long flags, @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo)862     private static boolean checkUseInstalledOrHidden(long flags,
863             @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo) {
864         // Returns false if the package is hidden system app until installed.
865         if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
866                 && !state.isInstalled()
867                 && appInfo != null && appInfo.hiddenUntilInstalled) {
868             return false;
869         }
870 
871         // If available for the target user, or trying to match uninstalled packages and it's
872         // a system app.
873         return PackageUserStateUtils.isAvailable(state, flags)
874                 || (appInfo != null && appInfo.isSystemApp() && matchUninstalledOrHidden(flags));
875     }
876 
matchUninstalledOrHidden(long flags)877     private static boolean matchUninstalledOrHidden(long flags) {
878         return (flags
879                 & (PackageManager.MATCH_KNOWN_PACKAGES
880                         | PackageManager.MATCH_ARCHIVED_PACKAGES
881                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS))
882                 != 0;
883     }
884 
assignFieldsComponentInfoParsedMainComponent( @onNull ComponentInfo info, @NonNull ParsedMainComponent component)885     private static void assignFieldsComponentInfoParsedMainComponent(
886             @NonNull ComponentInfo info, @NonNull ParsedMainComponent component) {
887         assignFieldsPackageItemInfoParsedComponent(info, component);
888         info.descriptionRes = component.getDescriptionRes();
889         info.directBootAware = component.isDirectBootAware();
890         info.enabled = component.isEnabled();
891         info.splitName = component.getSplitName();
892         info.attributionTags = component.getAttributionTags();
893     }
894 
assignFieldsPackageItemInfoParsedComponent( @onNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component)895     private static void assignFieldsPackageItemInfoParsedComponent(
896             @NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component) {
897         packageItemInfo.nonLocalizedLabel = ComponentParseUtils.getNonLocalizedLabel(component);
898         packageItemInfo.icon = ComponentParseUtils.getIcon(component);
899         packageItemInfo.banner = component.getBanner();
900         packageItemInfo.labelRes = component.getLabelRes();
901         packageItemInfo.logo = component.getLogo();
902         packageItemInfo.name = component.getName();
903         packageItemInfo.packageName = component.getPackageName();
904     }
905 
assignFieldsComponentInfoParsedMainComponent( @onNull ComponentInfo info, @NonNull ParsedMainComponent component, @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId)906     private static void assignFieldsComponentInfoParsedMainComponent(
907             @NonNull ComponentInfo info, @NonNull ParsedMainComponent component,
908             @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId) {
909         assignFieldsComponentInfoParsedMainComponent(info, component);
910         Pair<CharSequence, Integer> labelAndIcon =
911                 ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting,
912                         userId);
913         info.nonLocalizedLabel = labelAndIcon.first;
914         info.icon = labelAndIcon.second;
915     }
916 
assignFieldsPackageItemInfoParsedComponent( @onNull PackageItemInfo info, @NonNull ParsedComponent component, @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId)917     private static void assignFieldsPackageItemInfoParsedComponent(
918             @NonNull PackageItemInfo info, @NonNull ParsedComponent component,
919             @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId) {
920         assignFieldsPackageItemInfoParsedComponent(info, component);
921         Pair<CharSequence, Integer> labelAndIcon =
922                 ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting,
923                         userId);
924         info.nonLocalizedLabel = labelAndIcon.first;
925         info.icon = labelAndIcon.second;
926     }
927 
928     @CheckResult
flag(boolean hasFlag, int flag)929     private static int flag(boolean hasFlag, int flag) {
930         return hasFlag ? flag : 0;
931     }
932 
933     /**
934      * @see ApplicationInfo#flags
935      */
appInfoFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)936     public static int appInfoFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting) {
937         // @formatter:off
938         int pkgWithoutStateFlags = flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE)
939                 | flag(pkg.isHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
940                 | flag(pkg.isBackupAllowed(), ApplicationInfo.FLAG_ALLOW_BACKUP)
941                 | flag(pkg.isKillAfterRestoreAllowed(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
942                 | flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
943                 | flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY)
944                 | flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT)
945                 | flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE)
946                 | flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE)
947                 | flag(pkg.isDeclaredHavingCode(), ApplicationInfo.FLAG_HAS_CODE)
948                 | flag(pkg.isTaskReparentingAllowed(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
949                 | flag(pkg.isClearUserDataAllowed(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)
950                 | flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP)
951                 | flag(pkg.isCleartextTrafficAllowed(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC)
952                 | flag(pkg.isRtlSupported(), ApplicationInfo.FLAG_SUPPORTS_RTL)
953                 | flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY)
954                 | flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH)
955                 | flag(pkg.isExtractNativeLibrariesRequested(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS)
956                 | flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME)
957                 | flag(pkg.isSmallScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS)
958                 | flag(pkg.isNormalScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS)
959                 | flag(pkg.isLargeScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS)
960                 | flag(pkg.isExtraLargeScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)
961                 | flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS)
962                 | flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
963                 | flag(AndroidPackageLegacyUtils.isSystem(pkg), ApplicationInfo.FLAG_SYSTEM)
964                 | flag(pkg.isFactoryTest(), ApplicationInfo.FLAG_FACTORY_TEST);
965 
966         return appInfoFlags(pkgWithoutStateFlags, pkgSetting);
967         // @formatter:on
968     }
969 
970     /** @see ApplicationInfo#flags */
appInfoFlags(int pkgWithoutStateFlags, @NonNull PackageStateInternal pkgSetting)971     public static int appInfoFlags(int pkgWithoutStateFlags,
972             @NonNull PackageStateInternal pkgSetting) {
973         // @formatter:off
974         int flags = pkgWithoutStateFlags;
975         if (pkgSetting != null) {
976             flags |= flag(pkgSetting.isUpdatedSystemApp(), ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
977         }
978         return flags;
979         // @formatter:on
980     }
981 
982     /** @see ApplicationInfo#privateFlags */
appInfoPrivateFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)983     public static int appInfoPrivateFlags(AndroidPackage pkg,
984             @Nullable PackageStateInternal pkgSetting) {
985         // @formatter:off
986         int pkgWithoutStateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY)
987                 | flag(pkg.isResourceOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY)
988                 | flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING)
989                 | flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS)
990                 | flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL)
991                 | flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND)
992                 | flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX)
993                 | flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
994                 | flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE)
995                 | flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE)
996                 | flag(pkg.isClearUserDataOnFailedRestoreAllowed(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE)
997                 | flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE)
998                 | flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
999                 | flag(pkg.isNonSdkApiRequested(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API)
1000                 | flag(pkg.isUserDataFragile(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
1001                 | flag(pkg.isSaveStateDisallowed(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
1002                 | flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
1003                 | flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING)
1004                 | flag(AndroidPackageLegacyUtils.isSystemExt(pkg), ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT)
1005                 | flag(AndroidPackageLegacyUtils.isPrivileged(pkg), ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
1006                 | flag(AndroidPackageLegacyUtils.isOem(pkg), ApplicationInfo.PRIVATE_FLAG_OEM)
1007                 | flag(AndroidPackageLegacyUtils.isVendor(pkg), ApplicationInfo.PRIVATE_FLAG_VENDOR)
1008                 | flag(AndroidPackageLegacyUtils.isProduct(pkg), ApplicationInfo.PRIVATE_FLAG_PRODUCT)
1009                 | flag(AndroidPackageLegacyUtils.isOdm(pkg), ApplicationInfo.PRIVATE_FLAG_ODM)
1010                 | flag(pkg.isSignedWithPlatformKey(), ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY);
1011 
1012         Boolean resizeableActivity = pkg.getResizeableActivity();
1013         if (resizeableActivity != null) {
1014             if (resizeableActivity) {
1015                 pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
1016             } else {
1017                 pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
1018             }
1019         }
1020 
1021         return appInfoPrivateFlags(pkgWithoutStateFlags, pkgSetting);
1022         // @formatter:on
1023     }
1024 
1025     /** @see ApplicationInfo#privateFlags */
appInfoPrivateFlags(int pkgWithoutStateFlags, @Nullable PackageStateInternal pkgSetting)1026     public static int appInfoPrivateFlags(int pkgWithoutStateFlags,
1027             @Nullable PackageStateInternal pkgSetting) {
1028         // @formatter:off
1029         // TODO: Add state specific flags
1030         return pkgWithoutStateFlags;
1031         // @formatter:on
1032     }
1033 
1034     /** @see ApplicationInfo#privateFlagsExt */
appInfoPrivateFlagsExt(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)1035     public static int appInfoPrivateFlagsExt(AndroidPackage pkg,
1036                                              @Nullable PackageStateInternal pkgSetting) {
1037         var isAllowlistedForHiddenApis = SystemConfig.getInstance().getHiddenApiWhitelistedApps()
1038                 .contains(pkg.getPackageName());
1039         // @formatter:off
1040         int pkgWithoutStateFlags = flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
1041                 | flag(pkg.hasRequestForegroundServiceExemption(), ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION)
1042                 | flag(pkg.isAttributionsUserVisible(), ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE)
1043                 | flag(pkg.isOnBackInvokedCallbackEnabled(), ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK)
1044                 | flag(isAllowlistedForHiddenApis, ApplicationInfo.PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS);
1045         return appInfoPrivateFlagsExt(pkgWithoutStateFlags, pkgSetting);
1046         // @formatter:on
1047     }
1048 
1049     /** @see ApplicationInfo#privateFlagsExt */
appInfoPrivateFlagsExt(int pkgWithoutStateFlags, @Nullable PackageStateInternal pkgSetting)1050     private static int appInfoPrivateFlagsExt(int pkgWithoutStateFlags,
1051                                              @Nullable PackageStateInternal pkgSetting) {
1052         // @formatter:off
1053         int flags = pkgWithoutStateFlags;
1054         if (pkgSetting != null) {
1055             flags |= flag(pkgSetting.getCpuAbiOverride() != null, ApplicationInfo.PRIVATE_FLAG_EXT_CPU_OVERRIDE);
1056         }
1057         return flags;
1058         // @formatter:on
1059     }
1060 
initForUser(ApplicationInfo output, AndroidPackage input, @UserIdInt int userId, PackageUserStateInternal state)1061     private static void initForUser(ApplicationInfo output, AndroidPackage input,
1062             @UserIdInt int userId, PackageUserStateInternal state) {
1063         PackageImpl pkg = ((PackageImpl) input);
1064         String packageName = input.getPackageName();
1065         output.uid = UserHandle.getUid(userId, UserHandle.getAppId(input.getUid()));
1066 
1067         if ("android".equals(packageName)) {
1068             output.dataDir = SYSTEM_DATA_PATH;
1069             return;
1070         }
1071 
1072         if (!state.isInstalled() && !state.dataExists()
1073                 && android.content.pm.Flags.nullableDataDir()) {
1074             // The data dir has been deleted
1075             output.dataDir = null;
1076             return;
1077         }
1078 
1079         // For performance reasons, all these paths are built as strings
1080         if (userId == UserHandle.USER_SYSTEM) {
1081             output.credentialProtectedDataDir =
1082                     pkg.getBaseAppDataCredentialProtectedDirForSystemUser() + packageName;
1083             output.deviceProtectedDataDir =
1084                     pkg.getBaseAppDataDeviceProtectedDirForSystemUser() + packageName;
1085         } else {
1086             // Convert /data/user/0/ -> /data/user/1/com.example.app
1087             String userIdString = String.valueOf(userId);
1088             int credentialLength = pkg.getBaseAppDataCredentialProtectedDirForSystemUser().length();
1089             output.credentialProtectedDataDir =
1090                     new StringBuilder(pkg.getBaseAppDataCredentialProtectedDirForSystemUser())
1091                             .replace(credentialLength - 2, credentialLength - 1, userIdString)
1092                             .append(packageName)
1093                             .toString();
1094             int deviceLength = pkg.getBaseAppDataDeviceProtectedDirForSystemUser().length();
1095             output.deviceProtectedDataDir =
1096                     new StringBuilder(pkg.getBaseAppDataDeviceProtectedDirForSystemUser())
1097                             .replace(deviceLength - 2, deviceLength - 1, userIdString)
1098                             .append(packageName)
1099                             .toString();
1100         }
1101 
1102         if (input.isDefaultToDeviceProtectedStorage()
1103                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
1104             output.dataDir = output.deviceProtectedDataDir;
1105         } else {
1106             output.dataDir = output.credentialProtectedDataDir;
1107         }
1108     }
1109 
1110     // This duplicates the ApplicationInfo variant because it uses field assignment and the classes
1111     // don't inherit from each other, unfortunately. Consolidating logic would introduce overhead.
initForUser(InstrumentationInfo output, AndroidPackage input, @UserIdInt int userId, PackageUserStateInternal state)1112     private static void initForUser(InstrumentationInfo output, AndroidPackage input,
1113             @UserIdInt int userId, PackageUserStateInternal state) {
1114         PackageImpl pkg = ((PackageImpl) input);
1115         String packageName = input.getPackageName();
1116         if ("android".equals(packageName)) {
1117             output.dataDir = SYSTEM_DATA_PATH;
1118             return;
1119         }
1120 
1121         if (!state.isInstalled() && !state.dataExists()
1122                 && android.content.pm.Flags.nullableDataDir()) {
1123             // The data dir has been deleted
1124             output.dataDir = null;
1125             return;
1126         }
1127 
1128         // For performance reasons, all these paths are built as strings
1129         if (userId == UserHandle.USER_SYSTEM) {
1130             output.credentialProtectedDataDir =
1131                     pkg.getBaseAppDataCredentialProtectedDirForSystemUser() + packageName;
1132             output.deviceProtectedDataDir =
1133                     pkg.getBaseAppDataDeviceProtectedDirForSystemUser() + packageName;
1134         } else {
1135             // Convert /data/user/0/ -> /data/user/1/com.example.app
1136             String userIdString = String.valueOf(userId);
1137             int credentialLength = pkg.getBaseAppDataCredentialProtectedDirForSystemUser().length();
1138             output.credentialProtectedDataDir =
1139                     new StringBuilder(pkg.getBaseAppDataCredentialProtectedDirForSystemUser())
1140                             .replace(credentialLength - 2, credentialLength - 1, userIdString)
1141                             .append(packageName)
1142                             .toString();
1143             int deviceLength = pkg.getBaseAppDataDeviceProtectedDirForSystemUser().length();
1144             output.deviceProtectedDataDir =
1145                     new StringBuilder(pkg.getBaseAppDataDeviceProtectedDirForSystemUser())
1146                             .replace(deviceLength - 2, deviceLength - 1, userIdString)
1147                             .append(packageName)
1148                             .toString();
1149         }
1150 
1151         if (input.isDefaultToDeviceProtectedStorage()
1152                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
1153             output.dataDir = output.deviceProtectedDataDir;
1154         } else {
1155             output.dataDir = output.credentialProtectedDataDir;
1156         }
1157     }
1158 
1159     /**
1160      * Returns the data dir of the app for the target user. Return null if the app isn't installed
1161      * on the target user and doesn't have a data dir on the target user.
1162      */
1163     @Nullable
getDataDir(PackageStateInternal ps, int userId)1164     public static File getDataDir(PackageStateInternal ps, int userId) {
1165         if ("android".equals(ps.getPackageName())) {
1166             return Environment.getDataSystemDirectory();
1167         }
1168 
1169         if (!ps.getUserStateOrDefault(userId).isInstalled()
1170                 && !ps.getUserStateOrDefault(userId).dataExists()
1171                 && android.content.pm.Flags.nullableDataDir()) {
1172             // The app has been uninstalled for the user and the data dir has been deleted
1173             return null;
1174         }
1175 
1176         if (ps.isDefaultToDeviceProtectedStorage()
1177                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
1178             return Environment.getDataUserDePackageDirectory(ps.getVolumeUuid(), userId,
1179                     ps.getPackageName());
1180         } else {
1181             return Environment.getDataUserCePackageDirectory(ps.getVolumeUuid(), userId,
1182                     ps.getPackageName());
1183         }
1184     }
1185 
1186     /**
1187      * Wraps {@link PackageInfoUtils#generateApplicationInfo} with a cache.
1188      */
1189     public static class CachedApplicationInfoGenerator {
1190         // Map from a package name to the corresponding app info.
1191         private final ArrayMap<String, ApplicationInfo> mCache = new ArrayMap<>();
1192 
1193         /**
1194          * {@link PackageInfoUtils#generateApplicationInfo} with a cache.
1195          */
1196         @Nullable
generate(AndroidPackage pkg, @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting)1197         public ApplicationInfo generate(AndroidPackage pkg,
1198                 @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserStateInternal state,
1199                 int userId, @NonNull PackageStateInternal pkgSetting) {
1200             ApplicationInfo appInfo = mCache.get(pkg.getPackageName());
1201             if (appInfo != null) {
1202                 return appInfo;
1203             }
1204             appInfo = PackageInfoUtils.generateApplicationInfo(
1205                     pkg, flags, state, userId, pkgSetting);
1206             mCache.put(pkg.getPackageName(), appInfo);
1207             return appInfo;
1208         }
1209     }
1210 }
1211