• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.parsing;
18 
19 import android.annotation.CheckResult;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.apex.ApexInfo;
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.InstrumentationInfo;
32 import android.content.pm.PackageInfo;
33 import android.content.pm.PackageItemInfo;
34 import android.content.pm.PackageManager;
35 import android.content.pm.PathPermission;
36 import android.content.pm.PermissionGroupInfo;
37 import android.content.pm.PermissionInfo;
38 import android.content.pm.ProviderInfo;
39 import android.content.pm.ServiceInfo;
40 import android.content.pm.Signature;
41 import android.content.pm.SigningDetails;
42 import android.content.pm.SigningInfo;
43 import android.content.pm.overlay.OverlayPaths;
44 import android.os.Environment;
45 import android.os.PatternMatcher;
46 import android.os.UserHandle;
47 
48 import com.android.internal.util.ArrayUtils;
49 import com.android.server.pm.pkg.PackageUserState;
50 import com.android.server.pm.pkg.PackageUserStateUtils;
51 import com.android.server.pm.pkg.SELinuxUtil;
52 import com.android.server.pm.pkg.component.ComponentParseUtils;
53 import com.android.server.pm.pkg.component.ParsedActivity;
54 import com.android.server.pm.pkg.component.ParsedAttribution;
55 import com.android.server.pm.pkg.component.ParsedComponent;
56 import com.android.server.pm.pkg.component.ParsedInstrumentation;
57 import com.android.server.pm.pkg.component.ParsedMainComponent;
58 import com.android.server.pm.pkg.component.ParsedPermission;
59 import com.android.server.pm.pkg.component.ParsedPermissionGroup;
60 import com.android.server.pm.pkg.component.ParsedProvider;
61 import com.android.server.pm.pkg.component.ParsedService;
62 import com.android.server.pm.pkg.component.ParsedUsesPermission;
63 
64 import libcore.util.EmptyArray;
65 
66 import java.io.File;
67 import java.util.Collections;
68 import java.util.List;
69 import java.util.Set;
70 
71 /**
72  * @hide
73  **/
74 public class PackageInfoWithoutStateUtils {
75 
76     public static final String SYSTEM_DATA_PATH =
77             Environment.getDataDirectoryPath() + File.separator + "system";
78 
79     @Nullable
generate(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId)80     public static PackageInfo generate(ParsingPackageRead pkg, int[] gids,
81             @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
82             long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
83             int userId) {
84         return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions,
85                 state, userId, null);
86     }
87 
88     @Nullable
generate(ParsingPackageRead pkg, ApexInfo apexInfo, int flags)89     public static PackageInfo generate(ParsingPackageRead pkg, ApexInfo apexInfo, int flags) {
90         return generateWithComponents(pkg, EmptyArray.INT, flags, 0, 0, Collections.emptySet(),
91                 PackageUserState.DEFAULT, UserHandle.getCallingUserId(), apexInfo);
92     }
93 
94     @Nullable
generateWithComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo)95     private static PackageInfo generateWithComponents(ParsingPackageRead pkg, int[] gids,
96             @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
97             long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
98             int userId, @Nullable ApexInfo apexInfo) {
99         ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
100         if (applicationInfo == null) {
101             return null;
102         }
103         PackageInfo info = generateWithoutComponents(pkg, gids, flags, firstInstallTime,
104                 lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
105 
106         if (info == null) {
107             return null;
108         }
109 
110         if ((flags & PackageManager.GET_ACTIVITIES) != 0) {
111             final int N = pkg.getActivities().size();
112             if (N > 0) {
113                 int num = 0;
114                 final ActivityInfo[] res = new ActivityInfo[N];
115                 for (int i = 0; i < N; i++) {
116                     final ParsedActivity a = pkg.getActivities().get(i);
117                     if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
118                             flags)) {
119                         if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
120                                 a.getName())) {
121                             continue;
122                         }
123                         res[num++] = generateActivityInfo(pkg, a, flags, state,
124                                 applicationInfo, userId);
125                     }
126                 }
127                 info.activities = ArrayUtils.trimToSize(res, num);
128             }
129         }
130         if ((flags & PackageManager.GET_RECEIVERS) != 0) {
131             final int size = pkg.getReceivers().size();
132             if (size > 0) {
133                 int num = 0;
134                 final ActivityInfo[] res = new ActivityInfo[size];
135                 for (int i = 0; i < size; i++) {
136                     final ParsedActivity a = pkg.getReceivers().get(i);
137                     if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
138                             flags)) {
139                         res[num++] = generateActivityInfo(pkg, a, flags, state,
140                                 applicationInfo, userId);
141                     }
142                 }
143                 info.receivers = ArrayUtils.trimToSize(res, num);
144             }
145         }
146         if ((flags & PackageManager.GET_SERVICES) != 0) {
147             final int size = pkg.getServices().size();
148             if (size > 0) {
149                 int num = 0;
150                 final ServiceInfo[] res = new ServiceInfo[size];
151                 for (int i = 0; i < size; i++) {
152                     final ParsedService s = pkg.getServices().get(i);
153                     if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), s,
154                             flags)) {
155                         res[num++] = generateServiceInfo(pkg, s, flags, state,
156                                 applicationInfo, userId);
157                     }
158                 }
159                 info.services = ArrayUtils.trimToSize(res, num);
160             }
161         }
162         if ((flags & PackageManager.GET_PROVIDERS) != 0) {
163             final int size = pkg.getProviders().size();
164             if (size > 0) {
165                 int num = 0;
166                 final ProviderInfo[] res = new ProviderInfo[size];
167                 for (int i = 0; i < size; i++) {
168                     final ParsedProvider pr = pkg.getProviders()
169                             .get(i);
170                     if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), pr,
171                             flags)) {
172                         res[num++] = generateProviderInfo(pkg, pr, flags, state,
173                                 applicationInfo, userId);
174                     }
175                 }
176                 info.providers = ArrayUtils.trimToSize(res, num);
177             }
178         }
179         if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) {
180             int N = pkg.getInstrumentations().size();
181             if (N > 0) {
182                 info.instrumentation = new InstrumentationInfo[N];
183                 for (int i = 0; i < N; i++) {
184                     info.instrumentation[i] = generateInstrumentationInfo(
185                             pkg.getInstrumentations().get(i), pkg, flags, userId,
186                             true /* assignUserFields */);
187                 }
188             }
189         }
190 
191         return info;
192     }
193 
194     @Nullable
generateWithoutComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo)195     public static PackageInfo generateWithoutComponents(ParsingPackageRead pkg, int[] gids,
196             @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
197             long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
198             int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
199         if (!checkUseInstalled(pkg, state, flags)) {
200             return null;
201         }
202 
203         return generateWithoutComponentsUnchecked(pkg, gids, flags, firstInstallTime,
204                 lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
205     }
206 
207     /**
208      * This bypasses critical checks that are necessary for usage with data passed outside of system
209      * server.
210      * <p>
211      * Prefer {@link #generateWithoutComponents(ParsingPackageRead, int[], int, long, long, Set,
212      * PackageUserState, int, ApexInfo, ApplicationInfo)}.
213      */
214     @NonNull
generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo)215     public static PackageInfo generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids,
216             @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
217             long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
218             int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
219         PackageInfo pi = new PackageInfo();
220         pi.packageName = pkg.getPackageName();
221         pi.splitNames = pkg.getSplitNames();
222         pi.versionCode = ((ParsingPackageHidden) pkg).getVersionCode();
223         pi.versionCodeMajor = ((ParsingPackageHidden) pkg).getVersionCodeMajor();
224         pi.baseRevisionCode = pkg.getBaseRevisionCode();
225         pi.splitRevisionCodes = pkg.getSplitRevisionCodes();
226         pi.versionName = pkg.getVersionName();
227         pi.sharedUserId = pkg.getSharedUserId();
228         pi.sharedUserLabel = pkg.getSharedUserLabel();
229         pi.applicationInfo = applicationInfo;
230         pi.installLocation = pkg.getInstallLocation();
231         if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
232                 || (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
233             pi.requiredForAllUsers = pkg.isRequiredForAllUsers();
234         }
235         pi.restrictedAccountType = pkg.getRestrictedAccountType();
236         pi.requiredAccountType = pkg.getRequiredAccountType();
237         pi.overlayTarget = pkg.getOverlayTarget();
238         pi.targetOverlayableName = pkg.getOverlayTargetOverlayableName();
239         pi.overlayCategory = pkg.getOverlayCategory();
240         pi.overlayPriority = pkg.getOverlayPriority();
241         pi.mOverlayIsStatic = pkg.isOverlayIsStatic();
242         pi.compileSdkVersion = pkg.getCompileSdkVersion();
243         pi.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
244         pi.firstInstallTime = firstInstallTime;
245         pi.lastUpdateTime = lastUpdateTime;
246         if ((flags & PackageManager.GET_GIDS) != 0) {
247             pi.gids = gids;
248         }
249         if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) {
250             int size = pkg.getConfigPreferences().size();
251             if (size > 0) {
252                 pi.configPreferences = new ConfigurationInfo[size];
253                 pkg.getConfigPreferences().toArray(pi.configPreferences);
254             }
255             size = pkg.getRequestedFeatures().size();
256             if (size > 0) {
257                 pi.reqFeatures = new FeatureInfo[size];
258                 pkg.getRequestedFeatures().toArray(pi.reqFeatures);
259             }
260             size = pkg.getFeatureGroups().size();
261             if (size > 0) {
262                 pi.featureGroups = new FeatureGroupInfo[size];
263                 pkg.getFeatureGroups().toArray(pi.featureGroups);
264             }
265         }
266         if ((flags & PackageManager.GET_PERMISSIONS) != 0) {
267             int size = ArrayUtils.size(pkg.getPermissions());
268             if (size > 0) {
269                 pi.permissions = new PermissionInfo[size];
270                 for (int i = 0; i < size; i++) {
271                     pi.permissions[i] = generatePermissionInfo(pkg.getPermissions().get(i),
272                             flags);
273                 }
274             }
275             final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
276             size = usesPermissions.size();
277             if (size > 0) {
278                 pi.requestedPermissions = new String[size];
279                 pi.requestedPermissionsFlags = new int[size];
280                 for (int i = 0; i < size; i++) {
281                     final ParsedUsesPermission usesPermission = usesPermissions.get(i);
282                     pi.requestedPermissions[i] = usesPermission.getName();
283                     // The notion of required permissions is deprecated but for compatibility.
284                     pi.requestedPermissionsFlags[i] |=
285                             PackageInfo.REQUESTED_PERMISSION_REQUIRED;
286                     if (grantedPermissions != null
287                             && grantedPermissions.contains(usesPermission.getName())) {
288                         pi.requestedPermissionsFlags[i] |=
289                                 PackageInfo.REQUESTED_PERMISSION_GRANTED;
290                     }
291                     if ((usesPermission.getUsesPermissionFlags()
292                             & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
293                         pi.requestedPermissionsFlags[i] |=
294                                 PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
295                     }
296                 }
297             }
298         }
299         if ((flags & PackageManager.GET_ATTRIBUTIONS) != 0) {
300             int size = ArrayUtils.size(pkg.getAttributions());
301             if (size > 0) {
302                 pi.attributions = new Attribution[size];
303                 for (int i = 0; i < size; i++) {
304                     pi.attributions[i] = generateAttribution(pkg.getAttributions().get(i));
305                 }
306             }
307             if (pkg.areAttributionsUserVisible()) {
308                 pi.applicationInfo.privateFlagsExt
309                         |= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
310             } else {
311                 pi.applicationInfo.privateFlagsExt
312                         &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
313             }
314         } else {
315             pi.applicationInfo.privateFlagsExt
316                     &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
317         }
318 
319         if (apexInfo != null) {
320             File apexFile = new File(apexInfo.modulePath);
321 
322             pi.applicationInfo.sourceDir = apexFile.getPath();
323             pi.applicationInfo.publicSourceDir = apexFile.getPath();
324             if (apexInfo.isFactory) {
325                 pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
326                 pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
327             } else {
328                 pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
329                 pi.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
330             }
331             if (apexInfo.isActive) {
332                 pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
333             } else {
334                 pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
335             }
336             pi.isApex = true;
337         }
338 
339         final SigningDetails signingDetails = pkg.getSigningDetails();
340         // deprecated method of getting signing certificates
341         if ((flags & PackageManager.GET_SIGNATURES) != 0) {
342             if (signingDetails.hasPastSigningCertificates()) {
343                 // Package has included signing certificate rotation information.  Return the oldest
344                 // cert so that programmatic checks keep working even if unaware of key rotation.
345                 pi.signatures = new Signature[1];
346                 pi.signatures[0] = signingDetails.getPastSigningCertificates()[0];
347             } else if (signingDetails.hasSignatures()) {
348                 // otherwise keep old behavior
349                 int numberOfSigs = signingDetails.getSignatures().length;
350                 pi.signatures = new Signature[numberOfSigs];
351                 System.arraycopy(signingDetails.getSignatures(), 0, pi.signatures, 0,
352                         numberOfSigs);
353             }
354         }
355 
356         // replacement for GET_SIGNATURES
357         if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
358             if (signingDetails != SigningDetails.UNKNOWN) {
359                 // only return a valid SigningInfo if there is signing information to report
360                 pi.signingInfo = new SigningInfo(signingDetails);
361             } else {
362                 pi.signingInfo = null;
363             }
364         }
365 
366         return pi;
367     }
368 
369     @Nullable
generateApplicationInfo(ParsingPackageRead pkg, @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserState state, int userId)370     public static ApplicationInfo generateApplicationInfo(ParsingPackageRead pkg,
371             @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserState state,
372             int userId) {
373         if (pkg == null) {
374             return null;
375         }
376 
377         if (!checkUseInstalled(pkg, state, flags)) {
378             return null;
379         }
380 
381         return generateApplicationInfoUnchecked(pkg, flags, state, userId,
382                 true /* assignUserFields */);
383     }
384 
385     /**
386      * This bypasses critical checks that are necessary for usage with data passed outside of system
387      * server.
388      * <p>
389      * Prefer {@link #generateApplicationInfo(ParsingPackageRead, int, PackageUserState, int)}.
390      *
391      * @param assignUserFields whether to fill the returned {@link ApplicationInfo} with user
392      *                         specific fields. This can be skipped when building from a system
393      *                         server package, as there are cached strings which can be used rather
394      *                         than querying and concatenating the comparatively expensive {@link
395      *                         Environment#getDataDirectory(String)}}.
396      */
397     @NonNull
generateApplicationInfoUnchecked(@onNull ParsingPackageRead pkg, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserState state, int userId, boolean assignUserFields)398     public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg,
399             @PackageManager.ApplicationInfoFlagsBits long flags,
400             @NonNull PackageUserState state, int userId, boolean assignUserFields) {
401         // Make shallow copy so we can store the metadata/libraries safely
402         ApplicationInfo ai = ((ParsingPackageHidden) pkg).toAppInfoWithoutState();
403 
404         if (assignUserFields) {
405             assignUserFields(pkg, ai, userId);
406         }
407 
408         updateApplicationInfo(ai, flags, state);
409 
410         return ai;
411     }
412 
updateApplicationInfo(ApplicationInfo ai, long flags, PackageUserState state)413     private static void updateApplicationInfo(ApplicationInfo ai, long flags,
414             PackageUserState state) {
415         if ((flags & PackageManager.GET_META_DATA) == 0) {
416             ai.metaData = null;
417         }
418         if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) {
419             ai.sharedLibraryFiles = null;
420             ai.sharedLibraryInfos = null;
421         }
422 
423         // CompatibilityMode is global state.
424         if (!ParsingPackageUtils.sCompatibilityModeEnabled) {
425             ai.disableCompatibilityMode();
426         }
427 
428         ai.flags |= flag(state.isStopped(), ApplicationInfo.FLAG_STOPPED)
429                 | flag(state.isInstalled(), ApplicationInfo.FLAG_INSTALLED)
430                 | flag(state.isSuspended(), ApplicationInfo.FLAG_SUSPENDED);
431         ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT)
432                 | flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD)
433                 | flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN);
434 
435         if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
436             ai.enabled = true;
437         } else if (state.getEnabledState()
438                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
439             ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
440         } else if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
441                 || state.getEnabledState()
442                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
443             ai.enabled = false;
444         }
445         ai.enabledSetting = state.getEnabledState();
446         if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
447             ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
448         }
449         ai.seInfoUser = SELinuxUtil.getSeinfoUser(state);
450         final OverlayPaths overlayPaths = state.getAllOverlayPaths();
451         if (overlayPaths != null) {
452             ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
453             ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
454         }
455     }
456 
457     @Nullable
generateDelegateApplicationInfo(@ullable ApplicationInfo ai, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)458     public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai,
459             @PackageManager.ApplicationInfoFlagsBits long flags,
460             @NonNull PackageUserState state, int userId) {
461         if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) {
462             return null;
463         }
464         // This is used to return the ResolverActivity or instantAppInstallerActivity;
465         // we will just always make a copy.
466         ai = new ApplicationInfo(ai);
467         ai.initForUser(userId);
468         ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes
469                 : ai.iconRes;
470         updateApplicationInfo(ai, flags, state);
471         return ai;
472     }
473 
474     @Nullable
generateDelegateActivityInfo(@ullable ActivityInfo a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)475     public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a,
476             @PackageManager.ComponentInfoFlagsBits long flags,
477             @NonNull PackageUserState state, int userId) {
478         if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) {
479             return null;
480         }
481         // This is used to return the ResolverActivity or instantAppInstallerActivity;
482         // we will just always make a copy.
483         final ActivityInfo ai = new ActivityInfo(a);
484         ai.applicationInfo =
485                 generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId);
486         return ai;
487     }
488 
489     @Nullable
generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId)490     public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a,
491             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
492             @Nullable ApplicationInfo applicationInfo, int userId) {
493         if (a == null) return null;
494         if (!checkUseInstalled(pkg, state, flags)) {
495             return null;
496         }
497         if (applicationInfo == null) {
498             applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
499         }
500         if (applicationInfo == null) {
501             return null;
502         }
503 
504         return generateActivityInfoUnchecked(a, flags, applicationInfo);
505     }
506 
507     /**
508      * This bypasses critical checks that are necessary for usage with data passed outside of system
509      * server.
510      * <p>
511      * Prefer {@link #generateActivityInfo(ParsingPackageRead, ParsedActivity, long,
512      * PackageUserState, ApplicationInfo, int)}.
513      */
514     @NonNull
generateActivityInfoUnchecked(@onNull ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull ApplicationInfo applicationInfo)515     public static ActivityInfo generateActivityInfoUnchecked(@NonNull ParsedActivity a,
516             @PackageManager.ComponentInfoFlagsBits long flags,
517             @NonNull ApplicationInfo applicationInfo) {
518         // Make shallow copies so we can store the metadata safely
519         ActivityInfo ai = new ActivityInfo();
520         assignSharedFieldsForComponentInfo(ai, a);
521         ai.targetActivity = a.getTargetActivity();
522         ai.processName = a.getProcessName();
523         ai.exported = a.isExported();
524         ai.theme = a.getTheme();
525         ai.uiOptions = a.getUiOptions();
526         ai.parentActivityName = a.getParentActivityName();
527         ai.permission = a.getPermission();
528         ai.taskAffinity = a.getTaskAffinity();
529         ai.flags = a.getFlags();
530         ai.privateFlags = a.getPrivateFlags();
531         ai.launchMode = a.getLaunchMode();
532         ai.documentLaunchMode = a.getDocumentLaunchMode();
533         ai.maxRecents = a.getMaxRecents();
534         ai.configChanges = a.getConfigChanges();
535         ai.softInputMode = a.getSoftInputMode();
536         ai.persistableMode = a.getPersistableMode();
537         ai.lockTaskLaunchMode = a.getLockTaskLaunchMode();
538         ai.screenOrientation = a.getScreenOrientation();
539         ai.resizeMode = a.getResizeMode();
540         ai.setMaxAspectRatio(a.getMaxAspectRatio());
541         ai.setMinAspectRatio(a.getMinAspectRatio());
542         ai.supportsSizeChanges = a.isSupportsSizeChanges();
543         ai.requestedVrComponent = a.getRequestedVrComponent();
544         ai.rotationAnimation = a.getRotationAnimation();
545         ai.colorMode = a.getColorMode();
546         ai.windowLayout = a.getWindowLayout();
547         ai.attributionTags = a.getAttributionTags();
548         if ((flags & PackageManager.GET_META_DATA) != 0) {
549             var metaData = a.getMetaData();
550             // Backwards compatibility, coerce to null if empty
551             ai.metaData = metaData.isEmpty() ? null : metaData;
552         }
553         ai.applicationInfo = applicationInfo;
554         ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts());
555         return ai;
556     }
557 
558     @Nullable
generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, int userId)559     public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a,
560             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
561             int userId) {
562         return generateActivityInfo(pkg, a, flags, state, null, userId);
563     }
564 
565     @Nullable
generateServiceInfo(ParsingPackageRead pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId)566     public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s,
567             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
568             @Nullable ApplicationInfo applicationInfo, int userId) {
569         if (s == null) return null;
570         if (!checkUseInstalled(pkg, state, flags)) {
571             return null;
572         }
573         if (applicationInfo == null) {
574             applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
575         }
576         if (applicationInfo == null) {
577             return null;
578         }
579 
580         return generateServiceInfoUnchecked(s, flags,  applicationInfo);
581     }
582 
583     /**
584      * This bypasses critical checks that are necessary for usage with data passed outside of system
585      * server.
586      * <p>
587      * Prefer {@link #generateServiceInfo(ParsingPackageRead, ParsedService, long, PackageUserState,
588      * ApplicationInfo, int)}.
589      */
590     @NonNull
generateServiceInfoUnchecked(@onNull ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull ApplicationInfo applicationInfo)591     public static ServiceInfo generateServiceInfoUnchecked(@NonNull ParsedService s,
592             @PackageManager.ComponentInfoFlagsBits long flags,
593             @NonNull ApplicationInfo applicationInfo) {
594         // Make shallow copies so we can store the metadata safely
595         ServiceInfo si = new ServiceInfo();
596         assignSharedFieldsForComponentInfo(si, s);
597         si.exported = s.isExported();
598         si.flags = s.getFlags();
599         si.permission = s.getPermission();
600         si.processName = s.getProcessName();
601         si.mForegroundServiceType = s.getForegroundServiceType();
602         si.applicationInfo = applicationInfo;
603         if ((flags & PackageManager.GET_META_DATA) != 0) {
604             var metaData = s.getMetaData();
605             // Backwards compatibility, coerce to null if empty
606             si.metaData = metaData.isEmpty() ? null : metaData;
607         }
608         return si;
609     }
610 
611     @Nullable
generateServiceInfo(ParsingPackageRead pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, int userId)612     public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s,
613             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
614             int userId) {
615         return generateServiceInfo(pkg, s, flags, state, null, userId);
616     }
617 
618     @Nullable
generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId)619     public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p,
620             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
621             @Nullable ApplicationInfo applicationInfo, int userId) {
622         if (p == null) return null;
623         if (!checkUseInstalled(pkg, state, flags)) {
624             return null;
625         }
626         if (applicationInfo == null) {
627             applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
628         }
629         if (applicationInfo == null) {
630             return null;
631         }
632 
633         return generateProviderInfoUnchecked(p, flags, applicationInfo);
634     }
635 
636     /**
637      * This bypasses critical checks that are necessary for usage with data passed outside of system
638      * server.
639      * <p>
640      * Prefer {@link #generateProviderInfo(ParsingPackageRead, ParsedProvider, long,
641      * PackageUserState, ApplicationInfo, int)}.
642      */
643     @NonNull
generateProviderInfoUnchecked(@onNull ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull ApplicationInfo applicationInfo)644     public static ProviderInfo generateProviderInfoUnchecked(@NonNull ParsedProvider p,
645             @PackageManager.ComponentInfoFlagsBits long flags,
646             @NonNull ApplicationInfo applicationInfo) {
647         // Make shallow copies so we can store the metadata safely
648         ProviderInfo pi = new ProviderInfo();
649         assignSharedFieldsForComponentInfo(pi, p);
650         pi.exported = p.isExported();
651         pi.flags = p.getFlags();
652         pi.processName = p.getProcessName();
653         pi.authority = p.getAuthority();
654         pi.isSyncable = p.isSyncable();
655         pi.readPermission = p.getReadPermission();
656         pi.writePermission = p.getWritePermission();
657         pi.grantUriPermissions = p.isGrantUriPermissions();
658         pi.forceUriPermissions = p.isForceUriPermissions();
659         pi.multiprocess = p.isMultiProcess();
660         pi.initOrder = p.getInitOrder();
661         pi.uriPermissionPatterns = p.getUriPermissionPatterns().toArray(new PatternMatcher[0]);
662         pi.pathPermissions = p.getPathPermissions().toArray(new PathPermission[0]);
663         if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
664             pi.uriPermissionPatterns = null;
665         }
666         if ((flags & PackageManager.GET_META_DATA) != 0) {
667             var metaData = p.getMetaData();
668             // Backwards compatibility, coerce to null if empty
669             pi.metaData = metaData.isEmpty() ? null : metaData;
670         }
671         pi.applicationInfo = applicationInfo;
672         return pi;
673     }
674 
675     @Nullable
generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, int userId)676     public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p,
677             @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
678             int userId) {
679         return generateProviderInfo(pkg, p, flags, state, null, userId);
680     }
681 
682     /**
683      * @param assignUserFields see {@link #generateApplicationInfoUnchecked(ParsingPackageRead,
684      *                         long, PackageUserState, int, boolean)}
685      */
686     @Nullable
generateInstrumentationInfo(ParsedInstrumentation i, ParsingPackageRead pkg, @PackageManager.ComponentInfoFlagsBits long flags, int userId, boolean assignUserFields)687     public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
688             ParsingPackageRead pkg, @PackageManager.ComponentInfoFlagsBits long flags, int userId,
689             boolean assignUserFields) {
690         if (i == null) return null;
691 
692         InstrumentationInfo ii = new InstrumentationInfo();
693         assignSharedFieldsForPackageItemInfo(ii, i);
694         ii.targetPackage = i.getTargetPackage();
695         ii.targetProcesses = i.getTargetProcesses();
696         ii.handleProfiling = i.isHandleProfiling();
697         ii.functionalTest = i.isFunctionalTest();
698 
699         ii.sourceDir = pkg.getBaseApkPath();
700         ii.publicSourceDir = pkg.getBaseApkPath();
701         ii.splitNames = pkg.getSplitNames();
702         ii.splitSourceDirs = pkg.getSplitCodePaths().length == 0 ? null : pkg.getSplitCodePaths();
703         ii.splitPublicSourceDirs = pkg.getSplitCodePaths().length == 0
704                 ? null : pkg.getSplitCodePaths();
705         ii.splitDependencies = pkg.getSplitDependencies().size() == 0
706                 ? null : pkg.getSplitDependencies();
707 
708         if (assignUserFields) {
709             assignUserFields(pkg, ii, userId);
710         }
711 
712         if ((flags & PackageManager.GET_META_DATA) == 0) {
713             return ii;
714         }
715         var metaData = i.getMetaData();
716         // Backwards compatibility, coerce to null if empty
717         ii.metaData = metaData.isEmpty() ? null : metaData;
718         return ii;
719     }
720 
721     @Nullable
generatePermissionInfo(ParsedPermission p, @PackageManager.ComponentInfoFlagsBits long flags)722     public static PermissionInfo generatePermissionInfo(ParsedPermission p,
723             @PackageManager.ComponentInfoFlagsBits long flags) {
724         if (p == null) return null;
725 
726         PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission());
727 
728         assignSharedFieldsForPackageItemInfo(pi, p);
729 
730         pi.group = p.getGroup();
731         pi.requestRes = p.getRequestRes();
732         pi.protectionLevel = p.getProtectionLevel();
733         pi.descriptionRes = p.getDescriptionRes();
734         pi.flags = p.getFlags();
735         pi.knownCerts = p.getKnownCerts();
736 
737         if ((flags & PackageManager.GET_META_DATA) == 0) {
738             return pi;
739         }
740         var metaData = p.getMetaData();
741         // Backwards compatibility, coerce to null if empty
742         pi.metaData = metaData.isEmpty() ? null : metaData;
743         return pi;
744     }
745 
746     @Nullable
generatePermissionGroupInfo(ParsedPermissionGroup pg, @PackageManager.ComponentInfoFlagsBits long flags)747     public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg,
748             @PackageManager.ComponentInfoFlagsBits long flags) {
749         if (pg == null) return null;
750 
751         PermissionGroupInfo pgi = new PermissionGroupInfo(
752                 pg.getRequestDetailRes(),
753                 pg.getBackgroundRequestRes(),
754                 pg.getBackgroundRequestDetailRes()
755         );
756 
757         assignSharedFieldsForPackageItemInfo(pgi, pg);
758         pgi.descriptionRes = pg.getDescriptionRes();
759         pgi.priority = pg.getPriority();
760         pgi.requestRes = pg.getRequestRes();
761         pgi.flags = pg.getFlags();
762 
763         if ((flags & PackageManager.GET_META_DATA) == 0) {
764             return pgi;
765         }
766         var metaData = pg.getMetaData();
767         // Backwards compatibility, coerce to null if empty
768         pgi.metaData = metaData.isEmpty() ? null : metaData;
769         return pgi;
770     }
771 
772     @Nullable
generateAttribution(ParsedAttribution pa)773     public static Attribution generateAttribution(ParsedAttribution pa) {
774         if (pa == null) return null;
775         return new Attribution(pa.getTag(), pa.getLabel());
776     }
777 
checkUseInstalledOrHidden(long flags, @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo)778     private static boolean checkUseInstalledOrHidden(long flags,
779             @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo) {
780         // Returns false if the package is hidden system app until installed.
781         if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
782                 && !state.isInstalled()
783                 && appInfo != null && appInfo.hiddenUntilInstalled) {
784             return false;
785         }
786 
787         // If available for the target user, or trying to match uninstalled packages and it's
788         // a system app.
789         return PackageUserStateUtils.isAvailable(state, flags)
790                 || (appInfo != null && appInfo.isSystemApp()
791                 && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
792                 || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
793     }
794 
assignSharedFieldsForComponentInfo(@onNull ComponentInfo componentInfo, @NonNull ParsedMainComponent mainComponent)795     private static void assignSharedFieldsForComponentInfo(@NonNull ComponentInfo componentInfo,
796             @NonNull ParsedMainComponent mainComponent) {
797         assignSharedFieldsForPackageItemInfo(componentInfo, mainComponent);
798         componentInfo.descriptionRes = mainComponent.getDescriptionRes();
799         componentInfo.directBootAware = mainComponent.isDirectBootAware();
800         componentInfo.enabled = mainComponent.isEnabled();
801         componentInfo.splitName = mainComponent.getSplitName();
802         componentInfo.attributionTags = mainComponent.getAttributionTags();
803     }
804 
assignSharedFieldsForPackageItemInfo( @onNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component)805     private static void assignSharedFieldsForPackageItemInfo(
806             @NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component) {
807         packageItemInfo.nonLocalizedLabel = ComponentParseUtils.getNonLocalizedLabel(component);
808         packageItemInfo.icon = ComponentParseUtils.getIcon(component);
809 
810         packageItemInfo.banner = component.getBanner();
811         packageItemInfo.labelRes = component.getLabelRes();
812         packageItemInfo.logo = component.getLogo();
813         packageItemInfo.name = component.getName();
814         packageItemInfo.packageName = component.getPackageName();
815     }
816 
817     @CheckResult
flag(boolean hasFlag, int flag)818     private static int flag(boolean hasFlag, int flag) {
819         if (hasFlag) {
820             return flag;
821         } else {
822             return 0;
823         }
824     }
825 
826     /**
827      * @see ApplicationInfo#flags
828      */
appInfoFlags(ParsingPackageRead pkg)829     public static int appInfoFlags(ParsingPackageRead pkg) {
830         // @formatter:off
831         return flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE)
832                 | flag(pkg.isBaseHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
833                 | flag(pkg.isAllowBackup(), ApplicationInfo.FLAG_ALLOW_BACKUP)
834                 | flag(pkg.isKillAfterRestore(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
835                 | flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
836                 | flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY)
837                 | flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT)
838                 | flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE)
839                 | flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE)
840                 | flag(pkg.isHasCode(), ApplicationInfo.FLAG_HAS_CODE)
841                 | flag(pkg.isAllowTaskReparenting(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
842                 | flag(pkg.isAllowClearUserData(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)
843                 | flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP)
844                 | flag(pkg.isUsesCleartextTraffic(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC)
845                 | flag(pkg.isSupportsRtl(), ApplicationInfo.FLAG_SUPPORTS_RTL)
846                 | flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY)
847                 | flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH)
848                 | flag(pkg.isExtractNativeLibs(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS)
849                 | flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME)
850                 | flag(pkg.isSupportsSmallScreens(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS)
851                 | flag(pkg.isSupportsNormalScreens(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS)
852                 | flag(pkg.isSupportsLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS)
853                 | flag(pkg.isSupportsExtraLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)
854                 | flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS)
855                 | flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES);
856         // @formatter:on
857     }
858 
859     /** @see ApplicationInfo#privateFlags */
appInfoPrivateFlags(ParsingPackageRead pkg)860     public static int appInfoPrivateFlags(ParsingPackageRead pkg) {
861         // @formatter:off
862         int privateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY)
863                 | flag(pkg.isOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY)
864                 | flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING)
865                 | flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS)
866                 | flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL)
867                 | flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND)
868                 | flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX)
869                 | flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
870                 | flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE)
871                 | flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE)
872                 | flag(pkg.isAllowClearUserDataOnFailedRestore(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE)
873                 | flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE)
874                 | flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
875                 | flag(pkg.isUsesNonSdkApi(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API)
876                 | flag(pkg.isHasFragileUserData(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
877                 | flag(pkg.isCantSaveState(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
878                 | flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
879                 | flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING);
880         // @formatter:on
881 
882         Boolean resizeableActivity = pkg.getResizeableActivity();
883         if (resizeableActivity != null) {
884             if (resizeableActivity) {
885                 privateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
886             } else {
887                 privateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
888             }
889         }
890 
891         return privateFlags;
892     }
893 
894     /** @see ApplicationInfo#privateFlagsExt */
appInfoPrivateFlagsExt(ParsingPackageRead pkg)895     public static int appInfoPrivateFlagsExt(ParsingPackageRead pkg) {
896         // @formatter:off
897         int privateFlagsExt =
898                 flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
899                 | flag(pkg.hasRequestForegroundServiceExemption(),
900                         ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION)
901                 | flag(pkg.areAttributionsUserVisible(),
902                         ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE)
903                 | flag(pkg.isOnBackInvokedCallbackEnabled(),
904                         ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK);
905         // @formatter:on
906         return privateFlagsExt;
907     }
908 
checkUseInstalled(ParsingPackageRead pkg, PackageUserState state, @PackageManager.PackageInfoFlagsBits long flags)909     private static boolean checkUseInstalled(ParsingPackageRead pkg,
910             PackageUserState state, @PackageManager.PackageInfoFlagsBits long flags) {
911         // If available for the target user
912         return PackageUserStateUtils.isAvailable(state, flags);
913     }
914 
915     @NonNull
getDataDir(ParsingPackageRead pkg, int userId)916     public static File getDataDir(ParsingPackageRead pkg, int userId) {
917         if ("android".equals(pkg.getPackageName())) {
918             return Environment.getDataSystemDirectory();
919         }
920 
921         if (pkg.isDefaultToDeviceProtectedStorage()
922                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
923             return getDeviceProtectedDataDir(pkg, userId);
924         } else {
925             return getCredentialProtectedDataDir(pkg, userId);
926         }
927     }
928 
929     @NonNull
getDeviceProtectedDataDir(ParsingPackageRead pkg, int userId)930     public static File getDeviceProtectedDataDir(ParsingPackageRead pkg, int userId) {
931         return Environment.getDataUserDePackageDirectory(pkg.getVolumeUuid(), userId,
932                 pkg.getPackageName());
933     }
934 
935     @NonNull
getCredentialProtectedDataDir(ParsingPackageRead pkg, int userId)936     public static File getCredentialProtectedDataDir(ParsingPackageRead pkg, int userId) {
937         return Environment.getDataUserCePackageDirectory(pkg.getVolumeUuid(), userId,
938                 pkg.getPackageName());
939     }
940 
assignUserFields(ParsingPackageRead pkg, ApplicationInfo info, int userId)941     private static void assignUserFields(ParsingPackageRead pkg, ApplicationInfo info, int userId) {
942         // This behavior is undefined for no-state ApplicationInfos when called by a public API,
943         // since the uid is never assigned by the system. It will always effectively be appId 0.
944         info.uid = UserHandle.getUid(userId, UserHandle.getAppId(info.uid));
945 
946         String pkgName = pkg.getPackageName();
947         if ("android".equals(pkgName)) {
948             info.dataDir = SYSTEM_DATA_PATH;
949             return;
950         }
951 
952         // For performance reasons, all these paths are built as strings
953         String baseDataDirPrefix =
954                 Environment.getDataDirectoryPath(pkg.getVolumeUuid()) + File.separator;
955         String userIdPkgSuffix = File.separator + userId + File.separator + pkgName;
956         info.credentialProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_CE
957                 + userIdPkgSuffix;
958         info.deviceProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_DE + userIdPkgSuffix;
959 
960         if (pkg.isDefaultToDeviceProtectedStorage()
961                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
962             info.dataDir = info.deviceProtectedDataDir;
963         } else {
964             info.dataDir = info.credentialProtectedDataDir;
965         }
966     }
967 
assignUserFields(ParsingPackageRead pkg, InstrumentationInfo info, int userId)968     private static void assignUserFields(ParsingPackageRead pkg, InstrumentationInfo info,
969             int userId) {
970         String pkgName = pkg.getPackageName();
971         if ("android".equals(pkgName)) {
972             info.dataDir = SYSTEM_DATA_PATH;
973             return;
974         }
975 
976         // For performance reasons, all these paths are built as strings
977         String baseDataDirPrefix =
978                 Environment.getDataDirectoryPath(pkg.getVolumeUuid()) + File.separator;
979         String userIdPkgSuffix = File.separator + userId + File.separator + pkgName;
980         info.credentialProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_CE
981                 + userIdPkgSuffix;
982         info.deviceProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_DE + userIdPkgSuffix;
983 
984         if (pkg.isDefaultToDeviceProtectedStorage()
985                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
986             info.dataDir = info.deviceProtectedDataDir;
987         } else {
988             info.dataDir = info.credentialProtectedDataDir;
989         }
990     }
991 }
992