• Android 得到安装包的信息


    得到安装包的所有的信息

      一个APK安装包它的相关信息都配置在AndroidManifest.xml中,将它解析出来之后,是存放在PackageInfo类对象中,而PackageInfo类对象的生成相关代码,实现在PackageUtil类的getPackageInfo()方法中,看一下它的实现:

        @Nullable
        public static PackageInfo getPackageInfo(Context context, File sourceFile, int flags) {
            try {
                return context.getPackageManager().getPackageArchiveInfo(sourceFile.getAbsolutePath(),
                        flags);
            } catch (Exception ignored) {
                return null;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

      在这context一般是Activity实例,context.getPackageManager()得到的是ApplicationPackageManager实例。看一下它的getPackageArchiveInfo(sourceFile.getAbsolutePath(), flags)方法:

        @Nullable
        public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath,
                @PackageInfoFlags int flags) {
            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                    | PackageManager.MATCH_DIRECT_BOOT_AWARE)) == 0) {
                // Caller expressed no opinion about what encryption
                // aware/unaware components they want to see, so match both
                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
            }
    
            boolean collectCertificates = (flags & PackageManager.GET_SIGNATURES) != 0
                    || (flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0;
    
            ParseInput input = ParseTypeImpl.forParsingWithoutPlatformCompat().reset();
            ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefault(input,
                    new File(archiveFilePath), 0, getPermissionManager().getSplitPermissions(),
                    collectCertificates);
            if (result.isError()) {
                return null;
            }
            return PackageInfoWithoutStateUtils.generate(result.getResult(), null, flags, 0, 0, null,
                    new PackageUserState(), UserHandle.getCallingUserId());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

      在这里,会将 flags 添加PackageManager.MATCH_DIRECT_BOOT_AWARE和PackageManager.MATCH_DIRECT_BOOT_UNAWARE。collectCertificates 会为false,代表不会收集签名。
      这里的input 实际是ParseTypeImpl对象。它用来保存解析的结果。
      这里首先通过ParsingPackageUtils.parseDefault()得到APK安装包的解析信息,然后调用PackageInfoWithoutStateUtils.generate()得到PackageInfo对象。
      看一下PackageInfoWithoutStateUtils.generate()方法,了解一下PackageInfo对象是怎么生成的。这里UserHandle.getCallingUserId()是Binder调用方的user id,它是通过调用方的uid得到的,如果当前没处在Binder调用中,则它是当前应用的user id。
      PackageInfoWithoutStateUtils.generate()方法会在内部调用PackageInfoWithoutStateUtils的静态方法generateWithComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime, Set grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo),看一下它的实现:

        @Nullable
        private static PackageInfo generateWithComponents(ParsingPackageRead pkg, int[] gids,
                @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
                Set<String> grantedPermissions, PackageUserState state, int userId,
                @Nullable ApexInfo apexInfo) {
            ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
            if (applicationInfo == null) {
                return null;
            }
            PackageInfo info = generateWithoutComponents(pkg, gids, flags, firstInstallTime,
                    lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
    
            if (info == null) {
                return null;
            }
    
            if ((flags & PackageManager.GET_ACTIVITIES) != 0) {
                final int N = pkg.getActivities().size();
                if (N > 0) {
                    int num = 0;
                    final ActivityInfo[] res = new ActivityInfo[N];
                    for (int i = 0; i < N; i++) {
                        final ParsedActivity a = pkg.getActivities().get(i);
                        if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
                                flags)) {
                            if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
                                    a.getName())) {
                                continue;
                            }
                            res[num++] = generateActivityInfo(pkg, a, flags, state,
                                    applicationInfo, userId);
                        }
                    }
                    info.activities = ArrayUtils.trimToSize(res, num);
                }
            }
            if ((flags & PackageManager.GET_RECEIVERS) != 0) {
                final int size = pkg.getReceivers().size();
                if (size > 0) {
                    int num = 0;
                    final ActivityInfo[] res = new ActivityInfo[size];
                    for (int i = 0; i < size; i++) {
                        final ParsedActivity a = pkg.getReceivers().get(i);
                        if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
                                flags)) {
                            res[num++] = generateActivityInfo(pkg, a, flags, state,
                                    applicationInfo, userId);
                        }
                    }
                    info.receivers = ArrayUtils.trimToSize(res, num);
                }
            }
            if ((flags & PackageManager.GET_SERVICES) != 0) {
                final int size = pkg.getServices().size();
                if (size > 0) {
                    int num = 0;
                    final ServiceInfo[] res = new ServiceInfo[size];
                    for (int i = 0; i < size; i++) {
                        final ParsedService s = pkg.getServices().get(i);
                        if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), s,
                                flags)) {
                            res[num++] = generateServiceInfo(pkg, s, flags, state,
                                    applicationInfo, userId);
                        }
                    }
                    info.services = ArrayUtils.trimToSize(res, num);
                }
            }
            if ((flags & PackageManager.GET_PROVIDERS) != 0) {
                final int size = pkg.getProviders().size();
                if (size > 0) {
                    int num = 0;
                    final ProviderInfo[] res = new ProviderInfo[size];
                    for (int i = 0; i < size; i++) {
                        final ParsedProvider pr = pkg.getProviders()
                                .get(i);
                        if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), pr,
                                flags)) {
                            res[num++] = generateProviderInfo(pkg, pr, flags, state,
                                    applicationInfo, userId);
                        }
                    }
                    info.providers = ArrayUtils.trimToSize(res, num);
                }
            }
            if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) {
                int N = pkg.getInstrumentations().size();
                if (N > 0) {
                    info.instrumentation = new InstrumentationInfo[N];
                    for (int i = 0; i < N; i++) {
                        info.instrumentation[i] = generateInstrumentationInfo(
                                pkg.getInstrumentations().get(i), pkg, flags, userId,
                                true /* assignUserFields */);
                    }
                }
            }
    
            return info;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

      该方法首先通过generateApplicationInfo()方法得到ApplicationInfo对象,然后通过该对象作为参数调用generateWithoutComponents()方法得到PackageInfo对象info。接下来,再根据flags标识判断是否得到四大组件Activity、Receiver、Service、Provider的信息。再通过PackageManager.GET_INSTRUMENTATION标识,得到Instrumentation信息。

    生成ApplicationInfo对象

      它是由PackageInfoWithoutStateUtils类的generateApplicationInfo(ParsingPackageRead pkg, @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId)实现:

        @Nullable
        public static ApplicationInfo generateApplicationInfo(ParsingPackageRead pkg,
                @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId) {
            if (pkg == null) {
                return null;
            }
    
            if (!checkUseInstalled(pkg, state, flags)) {
                return null;
            }
    
            return generateApplicationInfoUnchecked(pkg, flags, state, userId,
                    true /* assignUserFields */);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

      pkg 不问为null,它是解析APK文件得到的所有相关信息,它实际是ParsingPackageImpl对象。详细见Android 解析APK包
      接着调用checkUseInstalled(pkg, state, flags)检查包的状态,如果返回false,则返回结果null。PackageUserState类用来描述包的每用户状态信息。它最终是调用PackageUserState类对象的isAvailable(int flags)方法实现,代码PackageUserState类对象的isAvailable(int flags)代码如下:

        /**
         * Test if this package is installed.
         */
        public boolean isAvailable(int flags) {
            // True if it is installed for this user and it is not hidden. If it is hidden,
            // still return true if the caller requested MATCH_UNINSTALLED_PACKAGES
            final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0;
            final boolean matchUninstalled = (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
            return matchAnyUser
                    || (this.installed
                            && (!this.hidden || matchUninstalled));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

      如果标签flags存在PackageManager.MATCH_ANY_USER标识,则代表满足任一用户。这种情况直接返回true。
      如果状态是installed并且不是隐藏,返回true。但是状态是installed并且是隐藏,这种情况下调用者如果带PackageManager.MATCH_UNINSTALLED_PACKAGES标识也返回true。
      在这里PackageUserState类对象是新建的,所以installed为true,hidden 为false。所以返回true。
      最后接着调用generateApplicationInfoUnchecked(pkg, flags, state, userId, true /* assignUserFields */),来生成ApplicationInfo对象,它的代码如下:

        @NonNull
        public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg,
                @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId,
                boolean assignUserFields) {
            // Make shallow copy so we can store the metadata/libraries safely
            ApplicationInfo ai = pkg.toAppInfoWithoutState();
    
            if (assignUserFields) {
                assignUserFields(pkg, ai, userId);
            }
    
            if ((flags & PackageManager.GET_META_DATA) == 0) {
                ai.metaData = null;
            }
            if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) {
                ai.sharedLibraryFiles = null;
                ai.sharedLibraryInfos = null;
            }
    
            // CompatibilityMode is global state.
            if (!android.content.pm.PackageParser.sCompatibilityModeEnabled) {
                ai.disableCompatibilityMode();
            }
    
            ai.flags |= flag(state.stopped, ApplicationInfo.FLAG_STOPPED)
                    | flag(state.installed, ApplicationInfo.FLAG_INSTALLED)
                    | flag(state.suspended, ApplicationInfo.FLAG_SUSPENDED);
            ai.privateFlags |= flag(state.instantApp, ApplicationInfo.PRIVATE_FLAG_INSTANT)
                    | flag(state.virtualPreload, ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD)
                    | flag(state.hidden, ApplicationInfo.PRIVATE_FLAG_HIDDEN);
    
            if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
                ai.enabled = true;
            } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
                ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
            } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                    || state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
                ai.enabled = false;
            }
            ai.enabledSetting = state.enabled;
            if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
                ai.category = state.categoryHint;
            }
            if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
                ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
            }
            ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
            final OverlayPaths overlayPaths = state.getAllOverlayPaths();
            if (overlayPaths != null) {
                ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
                ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
            }
    
            return ai;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

      这里通过ParsingPackageRead类对象pkg的toAppInfoWithoutState()得到ApplicationInfo对象。这里pkg是ParsingPackageImpl对象。所以这里调用的ParsingPackageImpl类的toAppInfoWithoutState()方法:

        @Deprecated
        @Override
        public ApplicationInfo toAppInfoWithoutState() {
            ApplicationInfo appInfo = toAppInfoWithoutStateWithoutFlags();
            appInfo.flags = PackageInfoWithoutStateUtils.appInfoFlags(this);
            appInfo.privateFlags = PackageInfoWithoutStateUtils.appInfoPrivateFlags(this);
            appInfo.privateFlagsExt = PackageInfoWithoutStateUtils.appInfoPrivateFlagsExt(this);
            return appInfo;
        }
    
        @Override
        public ApplicationInfo toAppInfoWithoutStateWithoutFlags() {
            ApplicationInfo appInfo = new ApplicationInfo();
    
            // Lines that are commented below are state related and should not be assigned here.
            // They are left in as placeholders, since there is no good backwards compatible way to
            // separate these.
            appInfo.appComponentFactory = appComponentFactory;
            appInfo.backupAgentName = backupAgentName;
            appInfo.banner = banner;
            appInfo.category = category;
            appInfo.classLoaderName = classLoaderName;
            appInfo.className = className;
            appInfo.compatibleWidthLimitDp = compatibleWidthLimitDp;
            appInfo.compileSdkVersion = compileSdkVersion;
            appInfo.compileSdkVersionCodename = compileSdkVersionCodeName;
    //        appInfo.credentialProtectedDataDir
            appInfo.crossProfile = isCrossProfile();
    //        appInfo.dataDir
            appInfo.descriptionRes = descriptionRes;
    //        appInfo.deviceProtectedDataDir
            appInfo.enabled = getBoolean(Booleans.ENABLED);
    //        appInfo.enabledSetting
            appInfo.fullBackupContent = fullBackupContent;
            appInfo.dataExtractionRulesRes = dataExtractionRules;
            // TODO(b/135203078): See ParsingPackageImpl#getHiddenApiEnforcementPolicy
    //        appInfo.mHiddenApiPolicy
    //        appInfo.hiddenUntilInstalled
            appInfo.icon =
                    (ParsingPackageUtils.sUseRoundIcon && roundIconRes != 0) ? roundIconRes : iconRes;
            appInfo.iconRes = iconRes;
            appInfo.roundIconRes = roundIconRes;
            appInfo.installLocation = installLocation;
            appInfo.labelRes = labelRes;
            appInfo.largestWidthLimitDp = largestWidthLimitDp;
            appInfo.logo = logo;
            appInfo.manageSpaceActivityName = manageSpaceActivityName;
            appInfo.maxAspectRatio = maxAspectRatio;
            appInfo.metaData = metaData;
            appInfo.minAspectRatio = minAspectRatio;
            appInfo.minSdkVersion = minSdkVersion;
            appInfo.name = className;
    //        appInfo.nativeLibraryDir
    //        appInfo.nativeLibraryRootDir
    //        appInfo.nativeLibraryRootRequiresIsa
            appInfo.networkSecurityConfigRes = networkSecurityConfigRes;
            appInfo.nonLocalizedLabel = nonLocalizedLabel;
            appInfo.packageName = packageName;
            appInfo.permission = permission;
    //        appInfo.primaryCpuAbi
            appInfo.processName = getProcessName();
            appInfo.requiresSmallestWidthDp = requiresSmallestWidthDp;
    //        appInfo.resourceDirs
    //        appInfo.secondaryCpuAbi
    //        appInfo.secondaryNativeLibraryDir
    //        appInfo.seInfo
    //        appInfo.seInfoUser
    //        appInfo.sharedLibraryFiles
    //        appInfo.sharedLibraryInfos
    //        appInfo.showUserIcon
            appInfo.splitClassLoaderNames = splitClassLoaderNames;
            appInfo.splitDependencies = splitDependencies;
            appInfo.splitNames = splitNames;
            appInfo.storageUuid = mStorageUuid;
            appInfo.targetSandboxVersion = targetSandboxVersion;
            appInfo.targetSdkVersion = targetSdkVersion;
            appInfo.taskAffinity = taskAffinity;
            appInfo.theme = theme;
    //        appInfo.uid
            appInfo.uiOptions = uiOptions;
            appInfo.volumeUuid = volumeUuid;
            appInfo.zygotePreloadName = zygotePreloadName;
            appInfo.setGwpAsanMode(gwpAsanMode);
            appInfo.setMemtagMode(memtagMode);
            appInfo.setNativeHeapZeroInitialized(nativeHeapZeroInitialized);
            appInfo.setRequestRawExternalStorageAccess(requestRawExternalStorageAccess);
            appInfo.setBaseCodePath(mBaseApkPath);
            appInfo.setBaseResourcePath(mBaseApkPath);
            appInfo.setCodePath(mPath);
            appInfo.setResourcePath(mPath);
            appInfo.setSplitCodePaths(splitCodePaths);
            appInfo.setSplitResourcePaths(splitCodePaths);
            appInfo.setVersionCode(mLongVersionCode);
    
            return appInfo;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

      从这里可以看到,主要是将ParsingPackageImpl对象的成员变量值赋给ApplicationInfo 类对象。
      再回到PackageInfoWithoutStateUtils类的generateApplicationInfoUnchecked(pkg, flags, state, userId, true /* assignUserFields */)方法里,接着assignUserFields如果为true,会调用assignUserFields(pkg, ai, userId),它主要是设置ApplicationInfo类对象的credentialProtectedDataDir、deviceProtectedDataDir、dataDir。
      接着会根据标识,判断是否设置ApplicationInfo类对象的metaData、sharedLibraryFiles、sharedLibraryInfos。
      下面主要是根据PackageUserState类对象state的值来设置一些对应的值。
      通过以上,我们明白了ApplicationInfo类对象的生成。

    生成PackageInfo对象

      PackageInfo对象的生成主要是由PackageInfoWithoutStateUtils的generateWithoutComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime, Set grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo)来生成,看一下它的代码:

        @Nullable
        public static PackageInfo generateWithoutComponents(ParsingPackageRead pkg, int[] gids,
                @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
                Set<String> grantedPermissions, PackageUserState state, int userId,
                @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
            if (!checkUseInstalled(pkg, state, flags)) {
                return null;
            }
    
            return generateWithoutComponentsUnchecked(pkg, gids, flags, firstInstallTime,
                    lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

      checkUseInstalled(pkg, state, flags)前面说过了,这里略了。接着看generateWithoutComponentsUnchecked()方法:

        @NonNull
        public static PackageInfo generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids,
                @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
                Set<String> grantedPermissions, PackageUserState state, int userId,
                @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
            PackageInfo pi = new PackageInfo();
            pi.packageName = pkg.getPackageName();
            pi.splitNames = pkg.getSplitNames();
            pi.versionCode = pkg.getVersionCode();
            pi.versionCodeMajor = pkg.getVersionCodeMajor();
            pi.baseRevisionCode = pkg.getBaseRevisionCode();
            pi.splitRevisionCodes = pkg.getSplitRevisionCodes();
            pi.versionName = pkg.getVersionName();
            pi.sharedUserId = pkg.getSharedUserId();
            pi.sharedUserLabel = pkg.getSharedUserLabel();
            pi.applicationInfo = applicationInfo;
            pi.installLocation = pkg.getInstallLocation();
            if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
                    || (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                pi.requiredForAllUsers = pkg.isRequiredForAllUsers();
            }
            pi.restrictedAccountType = pkg.getRestrictedAccountType();
            pi.requiredAccountType = pkg.getRequiredAccountType();
            pi.overlayTarget = pkg.getOverlayTarget();
            pi.targetOverlayableName = pkg.getOverlayTargetName();
            pi.overlayCategory = pkg.getOverlayCategory();
            pi.overlayPriority = pkg.getOverlayPriority();
            pi.mOverlayIsStatic = pkg.isOverlayIsStatic();
            pi.compileSdkVersion = pkg.getCompileSdkVersion();
            pi.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
            pi.firstInstallTime = firstInstallTime;
            pi.lastUpdateTime = lastUpdateTime;
            if ((flags & PackageManager.GET_GIDS) != 0) {
                pi.gids = gids;
            }
            if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) {
                int size = pkg.getConfigPreferences().size();
                if (size > 0) {
                    pi.configPreferences = new ConfigurationInfo[size];
                    pkg.getConfigPreferences().toArray(pi.configPreferences);
                }
                size = pkg.getReqFeatures().size();
                if (size > 0) {
                    pi.reqFeatures = new FeatureInfo[size];
                    pkg.getReqFeatures().toArray(pi.reqFeatures);
                }
                size = pkg.getFeatureGroups().size();
                if (size > 0) {
                    pi.featureGroups = new FeatureGroupInfo[size];
                    pkg.getFeatureGroups().toArray(pi.featureGroups);
                }
            }
            if ((flags & PackageManager.GET_PERMISSIONS) != 0) {
                int size = ArrayUtils.size(pkg.getPermissions());
                if (size > 0) {
                    pi.permissions = new PermissionInfo[size];
                    for (int i = 0; i < size; i++) {
                        pi.permissions[i] = generatePermissionInfo(pkg.getPermissions().get(i),
                                flags);
                    }
                }
                final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
                size = usesPermissions.size();
                if (size > 0) {
                    pi.requestedPermissions = new String[size];
                    pi.requestedPermissionsFlags = new int[size];
                    for (int i = 0; i < size; i++) {
                        final ParsedUsesPermission usesPermission = usesPermissions.get(i);
                        pi.requestedPermissions[i] = usesPermission.name;
                        // The notion of required permissions is deprecated but for compatibility.
                        pi.requestedPermissionsFlags[i] |=
                                PackageInfo.REQUESTED_PERMISSION_REQUIRED;
                        if (grantedPermissions != null
                                && grantedPermissions.contains(usesPermission.name)) {
                            pi.requestedPermissionsFlags[i] |=
                                    PackageInfo.REQUESTED_PERMISSION_GRANTED;
                        }
                        if ((usesPermission.usesPermissionFlags
                                & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
                            pi.requestedPermissionsFlags[i] |=
                                    PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
                        }
                    }
                }
            }
            if ((flags & PackageManager.GET_ATTRIBUTIONS) != 0) {
                int size = ArrayUtils.size(pkg.getAttributions());
                if (size > 0) {
                    pi.attributions = new Attribution[size];
                    for (int i = 0; i < size; i++) {
                        pi.attributions[i] = generateAttribution(pkg.getAttributions().get(i));
                    }
                }
                if (pkg.areAttributionsUserVisible()) {
                    pi.applicationInfo.privateFlagsExt
                            |= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
                } else {
                    pi.applicationInfo.privateFlagsExt
                            &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
                }
            } else {
                pi.applicationInfo.privateFlagsExt
                        &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
            }
    
            if (apexInfo != null) {
                File apexFile = new File(apexInfo.modulePath);
    
                pi.applicationInfo.sourceDir = apexFile.getPath();
                pi.applicationInfo.publicSourceDir = apexFile.getPath();
                if (apexInfo.isFactory) {
                    pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
                    pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
                } else {
                    pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
                    pi.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
                }
                if (apexInfo.isActive) {
                    pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
                } else {
                    pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
                }
                pi.isApex = true;
            }
    
            PackageParser.SigningDetails signingDetails = pkg.getSigningDetails();
            // deprecated method of getting signing certificates
            if ((flags & PackageManager.GET_SIGNATURES) != 0) {
                if (signingDetails.hasPastSigningCertificates()) {
                    // Package has included signing certificate rotation information.  Return the oldest
                    // cert so that programmatic checks keep working even if unaware of key rotation.
                    pi.signatures = new Signature[1];
                    pi.signatures[0] = signingDetails.pastSigningCertificates[0];
                } else if (signingDetails.hasSignatures()) {
                    // otherwise keep old behavior
                    int numberOfSigs = signingDetails.signatures.length;
                    pi.signatures = new Signature[numberOfSigs];
                    System.arraycopy(signingDetails.signatures, 0, pi.signatures, 0,
                            numberOfSigs);
                }
            }
    
            // replacement for GET_SIGNATURES
            if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
                if (signingDetails != PackageParser.SigningDetails.UNKNOWN) {
                    // only return a valid SigningInfo if there is signing information to report
                    pi.signingInfo = new SigningInfo(signingDetails);
                } else {
                    pi.signingInfo = null;
                }
            }
    
            return pi;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154

      这些代码看着很长,其实主要是新生成PackageInfo对象,然后给它的成员变量赋值。
      这里我们看到,前面生成的ApplicationInfo类对象是放到PackageInfo类对象的applicationInfo成员变量中。并且PackageInfo类对象大部分成员变量的值都来自ParsingPackageImpl类对象的成员变量的值。
      而ApplicationInfo类对象的值,大部分也都来自ParsingPackageImpl类对象。而ParsingPackageImpl类对象的值,也是来自安装包里的“AndroidManifest.xml”文件,这样就将ParsingPackageImpl类对象的值都设置到PackageInfo类对象中。

    总结

      APK安装包里的配置信息都在“AndroidManifest.xml”文件中,通过解析它之后,是放到了ParsingPackageImpl类对象中。ParsingPackageImpl类对象通过自己的toAppInfoWithoutState(),将自己的值生成到ApplicationInfo对象中,而PackageInfo类对象的applicationInfo正是ApplicationInfo对象,并且PackageInfo类对象的其他成员也来自ParsingPackageImpl类对象。这样PackageInfo类对象就包含了安装包的信息。

  • 相关阅读:
    中国互联网综合实力100强:猿辅导第39
    Oracle数据库:oracle组函数,聚合函数,多行函数,avg,sum,min,max,count,group by,having
    分闸合闸电源监视继电器JZZS-1120/DC220V
    leetcode做题笔记232. 用栈实现队列
    高等数学(第七版)同济大学 习题7-9 个人解答
    CMake
    【Flutter】包管理(11)Flutter JSON 反序列化 json_serializable 进阶 自定义序列化、嵌套的 JSON 对象
    ZooKeeper(一):基础介绍
    MySQL——统计函数count,合计函数sum,(avg,max,min)函数
    选择从众,还是唯一?
  • 原文地址:https://blog.csdn.net/q1165328963/article/details/134023435