android13#PackageManager

80 阅读22分钟

1.简介

主要学习下边几个方法:

  • resolveActivity :根据提供的intent返回最匹配的对象信息
  • getInstalledPackages:获取安装包列表
  • getInstalledApplications:同上,数据内容不太一样
  • getInstalledModules :获取安装的模块列表
  • checkSignatures :签名检查
  • getPreferredActivities :获取系统里所有的首选项信息,包括 IntentFilter以及activity
  • addPreferredActivity:设置某个意图对应的默认的组件

1.1.说明

  • getInstalledApplications 和 getInstalledPackages 返回的数据个数是一样,区别就是数据结构不一样。
  • PackageInfo 里边基本就是清单文件里的数据
  • ApplicationInfo 更多的像是安装的信息

>1.PackageInfo.java

看下里边都有哪些变量,这个是清单文件里的

public void writeToParcel(Parcel dest, int parcelableFlags) {
    final boolean prevAllowSquashing = dest.allowSquashing();
    dest.writeString8(packageName);
    dest.writeString8Array(splitNames);
    dest.writeInt(versionCode);
    dest.writeInt(versionCodeMajor);
    dest.writeString8(versionName);
    dest.writeInt(baseRevisionCode);
    dest.writeIntArray(splitRevisionCodes);
    dest.writeString8(sharedUserId);
    dest.writeInt(sharedUserLabel);
    if (applicationInfo != null) {
        dest.writeInt(1);
        applicationInfo.writeToParcel(dest, parcelableFlags);
    } else {
        dest.writeInt(0);
    }
    dest.writeLong(firstInstallTime);
    dest.writeLong(lastUpdateTime);
    dest.writeIntArray(gids);
    dest.writeTypedArray(activities, parcelableFlags);
    dest.writeTypedArray(receivers, parcelableFlags);
    dest.writeTypedArray(services, parcelableFlags);
    dest.writeTypedArray(providers, parcelableFlags);
    dest.writeTypedArray(instrumentation, parcelableFlags);
    dest.writeTypedArray(permissions, parcelableFlags);
    dest.writeString8Array(requestedPermissions);
    dest.writeIntArray(requestedPermissionsFlags);
    dest.writeTypedArray(signatures, parcelableFlags);
    dest.writeTypedArray(configPreferences, parcelableFlags);
    dest.writeTypedArray(reqFeatures, parcelableFlags);
    dest.writeTypedArray(featureGroups, parcelableFlags);
    dest.writeTypedArray(attributions, parcelableFlags);
    dest.writeInt(installLocation);
    dest.writeInt(isStub ? 1 : 0);
    dest.writeInt(coreApp ? 1 : 0);
    dest.writeInt(requiredForAllUsers ? 1 : 0);
    dest.writeString8(restrictedAccountType);
    dest.writeString8(requiredAccountType);
    dest.writeString8(overlayTarget);
    dest.writeString8(overlayCategory);
    dest.writeInt(overlayPriority);
    dest.writeBoolean(mOverlayIsStatic);
    dest.writeInt(compileSdkVersion);
    dest.writeString8(compileSdkVersionCodename);
    if (signingInfo != null) {
        dest.writeInt(1);
        signingInfo.writeToParcel(dest, parcelableFlags);
    } else {
        dest.writeInt(0);
    }
    dest.writeBoolean(isApex);
    dest.restoreAllowSquashing(prevAllowSquashing);
}

>2.ApplicationInfo.java

  • 这个更多的是清单文件里application标签下的
public class ApplicationInfo extends PackageItemInfo implements Parcelable {

public void writeToParcel(Parcel dest, int parcelableFlags) {
    if (dest.maybeWriteSquashed(this)) {
        return;
    }
    super.writeToParcel(dest, parcelableFlags);
    dest.writeString8(taskAffinity);
    dest.writeString8(permission);
    dest.writeString8(processName);
    dest.writeString8(className);
    dest.writeInt(theme);
    dest.writeInt(flags);
    dest.writeInt(privateFlags);
    dest.writeInt(privateFlagsExt);
    dest.writeInt(requiresSmallestWidthDp);
    dest.writeInt(compatibleWidthLimitDp);
    dest.writeInt(largestWidthLimitDp);
    if (storageUuid != null) {
        dest.writeInt(1);
        dest.writeLong(storageUuid.getMostSignificantBits());
        dest.writeLong(storageUuid.getLeastSignificantBits());
    } else {
        dest.writeInt(0);
    }
    dest.writeString8(scanSourceDir);
    dest.writeString8(scanPublicSourceDir);
    dest.writeString8(sourceDir);
    dest.writeString8(publicSourceDir);
    dest.writeString8Array(splitNames);
    dest.writeString8Array(splitSourceDirs);
    dest.writeString8Array(splitPublicSourceDirs);
    dest.writeSparseArray((SparseArray) splitDependencies);
    dest.writeString8(nativeLibraryDir);
    dest.writeString8(secondaryNativeLibraryDir);
    dest.writeString8(nativeLibraryRootDir);
    dest.writeInt(nativeLibraryRootRequiresIsa ? 1 : 0);
    dest.writeString8(primaryCpuAbi);
    dest.writeString8(secondaryCpuAbi);
    dest.writeString8Array(resourceDirs);
    dest.writeString8Array(overlayPaths);
    dest.writeString8(seInfo);
    dest.writeString8(seInfoUser);
    dest.writeString8Array(sharedLibraryFiles);
    dest.writeTypedList(sharedLibraryInfos);
    dest.writeString8(dataDir);
    dest.writeString8(deviceProtectedDataDir);
    dest.writeString8(credentialProtectedDataDir);
    dest.writeInt(uid);
    dest.writeInt(minSdkVersion);
    dest.writeInt(targetSdkVersion);
    dest.writeLong(longVersionCode);
    dest.writeInt(enabled ? 1 : 0);
    dest.writeInt(enabledSetting);
    dest.writeInt(installLocation);
    dest.writeString8(manageSpaceActivityName);
    dest.writeString8(backupAgentName);
    dest.writeInt(descriptionRes);
    dest.writeInt(uiOptions);
    dest.writeInt(fullBackupContent);
    dest.writeInt(dataExtractionRulesRes);
    dest.writeBoolean(crossProfile);
    dest.writeInt(networkSecurityConfigRes);
    dest.writeInt(category);
    dest.writeInt(targetSandboxVersion);
    dest.writeString8(classLoaderName);
    dest.writeString8Array(splitClassLoaderNames);
    dest.writeInt(compileSdkVersion);
    dest.writeString8(compileSdkVersionCodename);
    dest.writeString8(appComponentFactory);
    dest.writeInt(iconRes);
    dest.writeInt(roundIconRes);
    dest.writeInt(mHiddenApiPolicy);
    dest.writeInt(hiddenUntilInstalled ? 1 : 0);
    dest.writeString8(zygotePreloadName);
    dest.writeInt(gwpAsanMode);
    dest.writeInt(memtagMode);
    dest.writeInt(nativeHeapZeroInitialized);
    sForBoolean.parcel(requestRawExternalStorageAccess, dest, parcelableFlags);
    dest.writeLong(createTimestamp);
    if (mAppClassNamesByProcess == null) {
        dest.writeInt(0);
    } else {
        final int size = mAppClassNamesByProcess.size();
        dest.writeInt(size);
        for (int i = 0; i < size; i++) {
            dest.writeString(mAppClassNamesByProcess.keyAt(i));
            dest.writeString(mAppClassNamesByProcess.valueAt(i));
        }
    }
    dest.writeInt(localeConfigRes);
    sForStringSet.parcel(mKnownActivityEmbeddingCerts, dest, flags);
}

1.2.继承关系

>1.PackageManager

public abstract class PackageManager {

>2.ApplicationPackageManager

public class ApplicationPackageManager extends PackageManager {

>3.IPackageManagerBase

public abstract class IPackageManagerBase extends IPackageManager.Stub {

>4.IPackageManagerImpl

PackageManagerService的内部类

    public class IPackageManagerImpl extends IPackageManagerBase {

2.PackageManager

  • 我们通过context获取的对象,其实是ApplicationPackageManager
  • 这个包里方法,最终实现基本都在PMS的IPackageManagerImpl对象里
  • IPackageManagerImpl的实现又交给了ComputerEngine,参考小节3
PackageManagerService m;

        IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
        //这里注册的service,所以跨进程操作的就是这个对象
        ServiceManager.addService("package", iPackageManager);

2.1.resolveActivity

  • 根据提供的Intent查找到符合条件的对象返回
  • 和Intent的resolveActivity方法一样
  • 如果是隐式的意图(没有指定ComponentName),确认是否需要设置MATCH_DEFAULT_ONLY标志,
  • flag可以对结果进行过滤,比如MATCH_SYSTEM_ONLY只会返回系统应用,没有的话返回空
public abstract ResolveInfo resolveActivity(@NonNull Intent intent, int flags);

>1.ResolveInfoFlagsBits

看下支持的flag有哪些

@LongDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
        GET_META_DATA, 						//0x00000080;
        GET_RESOLVED_FILTER,        		//0x00000040;
        GET_SHARED_LIBRARY_FILES, 			//0x00000400;
        MATCH_ALL,                          //0x00020000;
        MATCH_DEBUG_TRIAGED_MISSING,        //0x10000000;
        MATCH_DISABLED_COMPONENTS,   		//0x00000200;
        MATCH_DISABLED_UNTIL_USED_COMPONENTS//0x00008000;
        MATCH_DEFAULT_ONLY,   				//0x00010000;
        MATCH_DIRECT_BOOT_AUTO,             //0x10000000;
        MATCH_DIRECT_BOOT_AWARE,            //0x00080000;
        MATCH_DIRECT_BOOT_UNAWARE,          //0x00040000;
        MATCH_SYSTEM_ONLY,                  //0x00100000;
        MATCH_UNINSTALLED_PACKAGES,         //0x00002000;
        MATCH_INSTANT,                      //0x00800000;
        GET_DISABLED_COMPONENTS,            //0x00000200;
        GET_DISABLED_UNTIL_USED_COMPONENTS, //0x00008000;
        GET_UNINSTALLED_PACKAGES,           //0x00002000;
})
@Retention(RetentionPolicy.SOURCE)
public @interface ResolveInfoFlagsBits {}

2.2.getInstalledPackages

  • 返回已安装的包信息,flags过滤返回的数据
  • 具体实现参考3.4
public abstract List<PackageInfo> getInstalledPackages(int flags);

>1.PackageInfoFlagsBits

@LongDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
        GET_ACTIVITIES,
        GET_CONFIGURATIONS,
        GET_GIDS,
        GET_INSTRUMENTATION,
        GET_INTENT_FILTERS,
        GET_META_DATA,
        GET_PERMISSIONS,
        GET_PROVIDERS,
        GET_RECEIVERS,
        GET_SERVICES,
        GET_SHARED_LIBRARY_FILES,
        GET_SIGNATURES,
        GET_SIGNING_CERTIFICATES,
        GET_URI_PERMISSION_PATTERNS,
        MATCH_UNINSTALLED_PACKAGES,
        MATCH_DISABLED_COMPONENTS,
        MATCH_DISABLED_UNTIL_USED_COMPONENTS,
        MATCH_SYSTEM_ONLY,
        MATCH_FACTORY_ONLY,
        MATCH_DEBUG_TRIAGED_MISSING,
        MATCH_INSTANT,
        MATCH_APEX,
        GET_DISABLED_COMPONENTS,
        GET_DISABLED_UNTIL_USED_COMPONENTS,
        GET_UNINSTALLED_PACKAGES,
        MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
        GET_ATTRIBUTIONS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PackageInfoFlagsBits {}

2.3.getInstalledApplications

  • 返回已安装的应用信息,具体实现参考3.5
public abstract List<ApplicationInfo> getInstalledApplications(int flags);

>1.ApplicationInfoFlagsBits

@LongDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
        GET_META_DATA,
        GET_SHARED_LIBRARY_FILES,
        MATCH_UNINSTALLED_PACKAGES,
        MATCH_SYSTEM_ONLY,
        MATCH_DEBUG_TRIAGED_MISSING,
        MATCH_DISABLED_COMPONENTS,
        MATCH_DISABLED_UNTIL_USED_COMPONENTS,
        MATCH_INSTANT,
        MATCH_STATIC_SHARED_AND_SDK_LIBRARIES,
        GET_DISABLED_UNTIL_USED_COMPONENTS,
        GET_UNINSTALLED_PACKAGES,
        MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
        MATCH_APEX,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ApplicationInfoFlagsBits {}

2.4.getInstalledModules

  • 返回已安装的所有模块
  • mPM的对应的IPackageManagerBase.java具体实现在PMS里
    private final IPackageManager mPM;
    
public List<ModuleInfo> getInstalledModules(@InstalledModulesFlags int flags) {
        try {
            return mPM.getInstalledModules(flags);
        } 

>1.InstalledModulesFlags

@IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
        MATCH_ALL,
})
@Retention(RetentionPolicy.SOURCE)
public @interface InstalledModulesFlags {}

>2.getInstalledModules

IPackageManagerBase.java

    public final List<ModuleInfo> getInstalledModules(int flags) {
        return mModuleInfoProvider.getInstalledModules(flags);
    }

2.5.checkSignatures

  • 判断两个包的签名是否一样,只有签名一样的才能共用uid
  • 返回值大于等于0,表示签名一样,小于0表示不一样。结果说明参考补充1
    public final int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
    //参考3.1
        return snapshot().checkSignatures(pkg1, pkg2);
    }

除了传递包名,还可以直接传递uid比较

public abstract @SignatureResult int checkSignatures(int uid1, int uid2);

>1.SignatureResult

  • 说明一下,一个包可能不止一个签名
@IntDef(prefix = { "SIGNATURE_" }, value = {
        SIGNATURE_MATCH, //0,所有签名都一样
        SIGNATURE_NEITHER_SIGNED, //1 ,2个包都没有签名
        SIGNATURE_FIRST_NOT_SIGNED, //-1 ,第一个没有签名,第二个有
        SIGNATURE_SECOND_NOT_SIGNED, //-2 ,第二个没有签名,第一个有
        SIGNATURE_NO_MATCH, //-3 ,签名不完全匹配
        SIGNATURE_UNKNOWN_PACKAGE, //-4, 2个包里有无效包
})
@Retention(RetentionPolicy.SOURCE)
public @interface SignatureResult {}

2.6.addPreferredActivity

一个intent查出来的activity有多个,这里是设置默认的一个。

>1.父类ApplicationPackageManager.java

  • filter:意图过滤器
  • match:意图要匹配的数据类型,比如IntentFilter.MATCH_CATEGORY_EMPTY,参考补充3
  • set :意图对应的所有组件集合
  • activity:set数组里的一种,就是我们要设置为默认值的那个
    private final IPackageManager mPM;//参考小节2开头注册的对象
    
    public void addPreferredActivity(IntentFilter filter,
                                     int match, ComponentName[] set, ComponentName activity) {
        try {//参考1.2.4,1.2.3,具体去这两个类里找
        //补充2
            mPM.addPreferredActivity(filter, match, set, activity, getUserId(), false);
        }
    }

>2.IPackageManagerBase.java

    public final void addPreferredActivity(IntentFilter filter, int match,
            ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
            //参考7.1
        mPreferredActivityHelper.addPreferredActivity(snapshot(),
                new WatchedIntentFilter(filter), match, set, activity, true, userId,
                "Adding preferred", removeExisting);
    }

>3.匹配类型

public static final int MATCH_CATEGORY_EMPTY = 0x0100000;
/**
 * The filter matched an intent with the same data URI scheme.
 */
public static final int MATCH_CATEGORY_SCHEME = 0x0200000;
/**
 * The filter matched an intent with the same data URI scheme and
 * authority host.
 */
public static final int MATCH_CATEGORY_HOST = 0x0300000;
/**
 * The filter matched an intent with the same data URI scheme and
 * authority host and port.
 */
public static final int MATCH_CATEGORY_PORT = 0x0400000;
/**
 * The filter matched an intent with the same data URI scheme,
 * authority, and path.
 */
public static final int MATCH_CATEGORY_PATH = 0x0500000;

2.7.getPreferredActivities

  • 获取系统所有意图和其对应的组件
  • 返回结果会在给定的outFilters和outActivities里,两者个数一样,一对一的关系
  • packageName为空,返回所有的,不为空的话过滤对应的包名返回
public abstract int getPreferredActivities(@NonNull List<IntentFilter> outFilters,
        @NonNull List<ComponentName> outActivities, @Nullable String packageName);

>1.如何使用

List<IntentFilter> outFilters =new ArrayList<>();
List<ComponentName> outActivities =new ArrayList<>();
getPackageManager().getPreferredActivities(outFilters,outActivities,null);
for (int i = 0; i < outFilters.size(); i++) {
    System.out.println("mytest====="+i+"=="+outFilters.get(i));
}
for (int i = 0; i < outActivities.size(); i++) {
    System.out.println("mytest====="+i+"==="+outActivities.get(i));
}

3.ComputerEngine.java

3.1.checkSignatures

检查签名是否一致

    public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
        final AndroidPackage p1 = mPackages.get(pkg1);
        final AndroidPackage p2 = mPackages.get(pkg2);
        final PackageStateInternal ps1 =//方法见3.2
                p1 == null ? null : getPackageStateInternal(p1.getPackageName());
        final PackageStateInternal ps2 =
                p2 == null ? null : getPackageStateInternal(p2.getPackageName());
        if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
            return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
        }
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        if (shouldFilterApplication(ps1, callingUid, callingUserId)
                || shouldFilterApplication(ps2, callingUid, callingUserId)) {
            return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
        }//补充1
        return checkSignaturesInternal(p1.getSigningDetails(), p2.getSigningDetails());
    }

    @Override
    public int checkUidSignatures(int uid1, int uid2) {
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        // Map to base uids.
        final int appId1 = UserHandle.getAppId(uid1);
        final int appId2 = UserHandle.getAppId(uid2);
        SigningDetails p1SigningDetails;
        SigningDetails p2SigningDetails;
        Object obj = mSettings.getSettingBase(appId1);
        if (obj != null) {
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                if (shouldFilterApplication(sus, callingUid, callingUserId)) {
                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                }
                p1SigningDetails = sus.signatures.mSigningDetails;
            } else if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                if (shouldFilterApplication(ps, callingUid, callingUserId)) {
                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                }
                p1SigningDetails = ps.getSigningDetails();
            } else {
                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
            }
        } else {
            return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
        }
        obj = mSettings.getSettingBase(appId2);
        if (obj != null) {
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                if (shouldFilterApplication(sus, callingUid, callingUserId)) {
                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                }
                p2SigningDetails = sus.signatures.mSigningDetails;
            } else if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                if (shouldFilterApplication(ps, callingUid, callingUserId)) {
                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                }
                p2SigningDetails = ps.getSigningDetails();
            } else {
                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
            }
        } else {
            return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
        }//补充1
        return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
    }

>1.checkSignaturesInternal

//不论是包名还是uid,最终都走到这里的

    private int checkSignaturesInternal(SigningDetails p1SigningDetails,
            SigningDetails p2SigningDetails) {
        if (p1SigningDetails == null) {
            return p2SigningDetails == null
                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
        }
        if (p2SigningDetails == null) {
            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
        }
        //这里比较的是新的签名
        int result = compareSignatures(p1SigningDetails.getSignatures(),
                p2SigningDetails.getSignatures());//补充2
        if (result == PackageManager.SIGNATURE_MATCH) {
            return result;
        }
        //这里比较旧的签名,有的话取第一个比较
        //为了支持与此API的客户端的向后兼容性,如果两个包中的任何一个具有签名沿袭,则期望预密钥旋转结果,沿袭中最老的签名者被用于签名验证。
        if (p1SigningDetails.hasPastSigningCertificates()
                || p2SigningDetails.hasPastSigningCertificates()) {
            Signature[] p1Signatures = p1SigningDetails.hasPastSigningCertificates()
                    ? new Signature[]{p1SigningDetails.getPastSigningCertificates()[0]}
                    : p1SigningDetails.getSignatures();
            Signature[] p2Signatures = p2SigningDetails.hasPastSigningCertificates()
                    ? new Signature[]{p2SigningDetails.getPastSigningCertificates()[0]}
                    : p2SigningDetails.getSignatures();
            result = compareSignatures(p1Signatures, p2Signatures);//补充2
        }
        return result;
    }

>2.compareSignatures

PackageManagerServiceUtils,判断2个签名数组是否一样

    public static int compareSignatures(Signature[] s1, Signature[] s2) {
        if (s1 == null) {
            return s2 == null
                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
        }

        if (s2 == null) {
            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
        }

        if (s1.length != s2.length) {
            return PackageManager.SIGNATURE_NO_MATCH;
        }

        // 由于两个签名集的大小都是1,所以我们可以在没有hashset的情况下进行比较
        if (s1.length == 1) {
            return s1[0].equals(s2[0]) ?
                    PackageManager.SIGNATURE_MATCH :
                    PackageManager.SIGNATURE_NO_MATCH;
        }

        ArraySet<Signature> set1 = new ArraySet<Signature>();
        for (Signature sig : s1) {
            set1.add(sig);
        }
        ArraySet<Signature> set2 = new ArraySet<Signature>();
        for (Signature sig : s2) {
            set2.add(sig);
        }
        //确保s2包含s1中的所有签名
        if (set1.equals(set2)) {
            return PackageManager.SIGNATURE_MATCH;
        }
        return PackageManager.SIGNATURE_NO_MATCH;
    }

3.2.getPackageStateInternal

根据包名获取包信息

    public final PackageStateInternal getPackageStateInternal(String packageName) {
        return getPackageStateInternal(packageName, Binder.getCallingUid());
    }

    public PackageStateInternal getPackageStateInternal(String packageName,
            int callingUid) {
        packageName = resolveInternalPackageNameInternalLocked(
                packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
        return mSettings.getPackage(packageName);
    }

3.3.shouldFilterApplication

    public final boolean shouldFilterApplication(
            @Nullable PackageStateInternal ps, int callingUid, int userId) {
        return shouldFilterApplication(ps, callingUid, null, TYPE_UNKNOWN, userId);
    }

>1.shouldFilterApplication

应用是否可以被访问,主要过滤的是instant app

    public final boolean shouldFilterApplication(@Nullable PackageStateInternal ps,
            int callingUid, @Nullable ComponentName component,
            @PackageManager.ComponentType int componentType, int userId) {
        if (Process.isSdkSandboxUid(callingUid)) {
            int clientAppUid = Process.getAppUidForSdkSandboxUid(callingUid);
            if (ps != null && clientAppUid == UserHandle.getUid(userId, ps.getAppId())) {
                return false;
            }
        }
        //如果我们在一个孤立的进程中,获取真正的调用UID
        if (Process.isIsolated(callingUid)) {
            callingUid = getIsolatedOwner(callingUid);
        }
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        final boolean callerIsInstantApp = instantAppPkgName != null;
        if (ps == null) {
            //假设应用程序存在,但是需要进行过滤
            return callerIsInstantApp || Process.isSdkSandboxUid(callingUid);
        }
        // 如果目标和调用者是同一个应用程序,不要过滤
        if (isCallerSameApp(ps.getPackageName(), callingUid)) {
            return false;
        }
        if (callerIsInstantApp) {
            // 调用者和目标都是即时的,但是不同的应用程序,过滤
            if (ps.getUserStateOrDefault(userId).isInstantApp()) {
                return true;
            }

            //请求的是特定的组件,
            if (component != null) {
                final ParsedInstrumentation instrumentation =
                        mInstrumentation.get(component);
                if (instrumentation != null
                        && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) {
                    return false;
                }
                //看组件是否对即时应用可见
                return !isComponentVisibleToInstantApp(component, componentType);
            }
            // request for application; if no components have been explicitly exposed, filter
            return !ps.getPkg().isVisibleToInstantApps();
        }
        if (ps.getUserStateOrDefault(userId).isInstantApp()) {
            // 调用者可以看到所有即时应用程序的所有组件,不要过滤,3.8
            if (canViewInstantApps(callingUid, userId)) {
                return false;
            }
            // 请求一个特定的即时应用程序组件,过滤
            if (component != null) {
                return true;
            }
            //请求的是一个即时应用,而调用者还没有被赋予权限,过滤掉
            return !mInstantAppRegistry.isInstantAccessGranted(
                    userId, UserHandle.getAppId(callingUid), ps.getAppId());
        }
        int appId = UserHandle.getAppId(callingUid);
        final SettingBase callingPs = mSettings.getSettingBase(appId);
        return mAppsFilter.shouldFilterApplication(this, callingUid, callingPs, ps, userId);
    }

3.4.getInstalledPackages

    public final ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId) {
        final int callingUid = Binder.getCallingUid();
        //调用者是instant app,返回空
        if (getInstantAppPackageName(callingUid) != null) {
            return ParceledListSlice.emptyList();
        }
        //用户不存在,返回空
        if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
        //权限检查
        flags = updateFlagsForPackage(flags, userId);

        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
                false /* checkShell */, "get installed packages");
//补充1
        return getInstalledPackagesBody(flags, userId, callingUid);
    }

>1.getInstalledPackagesBody

  • 可以看到安装包的数据都在mSettings里存着了,这个后边学习PMS再研究
    protected ParceledListSlice<PackageInfo> getInstalledPackagesBody(long flags, int userId,
            int callingUid) {

        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
        final boolean listApex = (flags & MATCH_APEX) != 0;
        //只包括系统映像上的组件。这将不会返回任何未绑定更新到系统组件的信息
        final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;

        ArrayList<PackageInfo> list;
        //包含未安装的包
        if (listUninstalled) {
            list = new ArrayList<>(mSettings.getPackages().size());
            for (PackageStateInternal ps : mSettings.getPackages().values()) {
                if (listFactory) {
                    if (!ps.isSystem()) {
                        continue;
                    }
                    PackageStateInternal psDisabled =
                            mSettings.getDisabledSystemPkg(ps.getPackageName());
                    if (psDisabled != null) {
                        ps = psDisabled;
                    }
                }
                if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
                    continue;
                }
                //参考3.3
                if (shouldFilterApplication(ps, callingUid, userId)) {
                    continue;
                }
                final PackageInfo pi = generatePackageInfo(ps, flags, userId);
                if (pi != null) {
                    list.add(pi);
                }
            }
        } else {
            list = new ArrayList<>(mPackages.size());
            for (AndroidPackage p : mPackages.values()) {
                PackageStateInternal ps = getPackageStateInternal(p.getPackageName());
                if (listFactory) {
                    if (!p.isSystem()) {
                        continue;
                    }
                    PackageStateInternal psDisabled =
                            ps == null ? null : mSettings.getDisabledSystemPkg(ps.getPackageName());
                    if (psDisabled != null) {
                        ps = psDisabled;
                    }
                }
                if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
                    continue;
                }
                if (shouldFilterApplication(ps, callingUid, userId)) {
                    continue;
                }
                final PackageInfo pi = generatePackageInfo(ps, flags, userId);
                if (pi != null) {
                    list.add(pi);
                }
            }
        }
        //需要apxe包的话,添加对应的数据
        if (listApex) {
            if (listFactory) {
                list.addAll(mApexManager.getFactoryPackages());
            } else {
                list.addAll(mApexManager.getActivePackages());
                if (listUninstalled) {
                    list.addAll(mApexManager.getInactivePackages());
                }
            }
        }
        return new ParceledListSlice<>(list);
    }

3.5.getInstalledApplications

    public List<ApplicationInfo> getInstalledApplications(
            @PackageManager.ApplicationInfoFlagsBits long flags, @UserIdInt int userId,
            int callingUid, boolean forceAllowCrossUser) {
        if (getInstantAppPackageName(callingUid) != null) {
            return Collections.emptyList();
        }
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        flags = updateFlagsForApplication(flags, userId);
        //根据flag判定是否列出未安装的包,apex包等
        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
        final boolean listApex = (flags & MATCH_APEX) != 0;
        final boolean listArchivedOnly = !listUninstalled && (flags & MATCH_ARCHIVED_PACKAGES) != 0;

        if (!forceAllowCrossUser) {
            enforceCrossUserPermission(
                    callingUid,
                    userId,
                    false /* requireFullPermission */,
                    false /* checkShell */,
                    "get installed application info");
        }

        ArrayList<ApplicationInfo> list;
        final ArrayMap<String, ? extends PackageStateInternal> packageStates =
                getPackageStates();//参考补充1,
        if (listUninstalled || listArchivedOnly) {
            list = new ArrayList<>(packageStates.size());
            for (PackageStateInternal ps : packageStates.values()) {
                ApplicationInfo ai;
                long effectiveFlags = flags;
                if (ps.isSystem()) {
                    effectiveFlags |= PackageManager.MATCH_ANY_USER;
                }
                if (ps.getPkg() != null) {
                    if (!listApex && ps.getPkg().isApex()) {
                        continue;
                    }
                    PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
                    if (listArchivedOnly && !userState.isInstalled()
                            && userState.getArchiveState() == null) {
                        continue;
                    }
                    if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
                        continue;
                    }//参考3.3
                    if (shouldFilterApplication(ps, callingUid, userId)) {
                        continue;
                    }
                    ai = PackageInfoUtils.generateApplicationInfo(ps.getPkg(), effectiveFlags,
                            ps.getUserStateOrDefault(userId), userId, ps);
                    if (ai != null) {
                        ai.packageName = resolveExternalPackageName(ps.getPkg());
                    }
                } else {
             // 共享库在调用generateApplicationInfoFromSettingsLPw进行过滤时, 已经转化为外部可见的包名
                    ai = generateApplicationInfoFromSettings(ps.getPackageName(),
                            effectiveFlags, callingUid, userId);
                }
                if (ai != null) {
                    list.add(ai);
                }
            }
        } else {
            list = new ArrayList<>(mPackages.size());
            for (PackageStateInternal packageState : packageStates.values()) {
                final AndroidPackage pkg = packageState.getPkg();
                if (pkg == null) {
                    continue;
                }
                if (!listApex && pkg.isApex()) {
                    continue;
                }
                if (filterSharedLibPackage(packageState, Binder.getCallingUid(), userId, flags)) {
                    continue;
                }//参考3.3
                if (shouldFilterApplication(packageState, callingUid, userId)) {
                    continue;
                }
                ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(pkg, flags,
                        packageState.getUserStateOrDefault(userId), userId, packageState);
                if (ai != null) {
                    ai.packageName = resolveExternalPackageName(pkg);
                    list.add(ai);
                }
            }
        }

        return list;
    }

>1.getPackageStates

数据来源依旧是mSettings,这个解析包的时候会存储在本地以及缓存里

    public ArrayMap<String, ? extends PackageStateInternal> getPackageStates() {
        return mSettings.getPackages();
    }

3.6.findPreferredActivityInternal

  • 获取对应intent的首选activity
    public final PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            List<ResolveInfo> query, boolean always,
            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {

        final int callingUid = Binder.getCallingUid();
        final boolean isDeviceProvisioned =
                android.provider.Settings.Global.getInt(mContext.getContentResolver(),
                        android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
        //补充1
        return findPreferredActivityBody(
                intent, resolvedType, flags, query, always, removeMatches, debug,
                userId, queryMayBeFiltered, callingUid, isDeviceProvisioned);
    }

>1.findPreferredActivityBody

    protected PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityBody(
    //.
    {
        PackageManagerService.FindPreferredActivityBodyResult
                result = new PackageManagerService.FindPreferredActivityBodyResult();

        flags = updateFlagsForResolve(
                flags, userId, callingUid, false /*includeInstantApps*/,
                isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId,
                        resolvedType, flags));
        intent = PackageManagerServiceUtils.updateIntentForResolve(intent);

        //尝试找到匹配的持久首选活动
        result.mPreferredResolveInfo = findPersistentPreferredActivity(intent,
                resolvedType, flags, query, debug, userId);

        //有的话返回
        if (result.mPreferredResolveInfo != null) {
            return result;
        }

        PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
        //根据意图查找
        List<PreferredActivity> prefs = pir != null
                ? pir.queryIntent(this, intent, resolvedType,
                (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
                userId)
                : null;
        if (prefs != null && prefs.size() > 0) {
            int match = 0;

            final int n = query.size();
            for (int j = 0; j < n; j++) {
                final ResolveInfo ri = query.get(j);
                if (ri.match > match) {
                    match = ri.match;
                }
            }
            match &= IntentFilter.MATCH_CATEGORY_MASK;
            final int m = prefs.size();
            for (int i = 0; i < m; i++) {
                final PreferredActivity pa = prefs.get(i);
                if (pa.mPref.mMatch != match) {
                    continue;
                }
                /
                if (always && !pa.mPref.mAlways) {
                  //需求是always的,pref不是always的,忽略
                    continue;
                }
                final ActivityInfo ai = getActivityInfo(
                        pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
                                | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                        userId);
//桌面意图并且还没有完成引导
                final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
                        && !isDeviceProvisioned;
                final boolean allowSetMutation = !excludeSetupWizardHomeActivity
                        && !queryMayBeFiltered;
                if (ai == null) {
                    //在安装向导期间不删除启动器的首选活动,因为它可能还没有安装
                    if (!allowSetMutation) {
                        continue;
                    }
                    pir.removeFilter(pa);
                    result.mChanged = true;
                    continue;
                }
                for (int j = 0; j < n; j++) {
                    final ResolveInfo ri = query.get(j);
                    //包名不一样的
                    if (!ri.activityInfo.applicationInfo.packageName
                            .equals(ai.applicationInfo.packageName)) {
                        continue;
                    }
                    //类名不一样的
                    if (!ri.activityInfo.name.equals(ai.name)) {
                        continue;
                    }

                    if (removeMatches && allowSetMutation) {
                        pir.removeFilter(pa);
                        result.mChanged = true;
                        break;
                    }

                    if (always//参考7.3.1
                            && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity, userId)) {
                            //参考7.3.2
                        if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
                            if (allowSetMutation) {

                                PreferredActivity freshPa = new PreferredActivity(pa,
                                        pa.mPref.mMatch,
                                        pa.mPref.discardObsoleteComponents(query),
                                        pa.mPref.mComponent,
                                        pa.mPref.mAlways);
                                pir.removeFilter(pa);
                                pir.addFilter(this, freshPa);
                                result.mChanged = true;
                            }
                        } else {
                            if (allowSetMutation) {
      
                                pir.removeFilter(pa);

                                PreferredActivity lastChosen = new PreferredActivity(
                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent,
                                        false);
                                pir.addFilter(this, lastChosen);
                                result.mChanged = true;
                            }
                            result.mPreferredResolveInfo = null;
                            return result;
                        }
                    }

                    result.mPreferredResolveInfo = ri;
                    return result;
                }
            }
        }
        return result;
    }

3.7.queryIntentActivitiesInternal

根据intent查找对应的活动集合

    public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
            int filterCallingUid, int userId, boolean resolveForStart,
            boolean allowDynamicSplits) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
        enforceCrossUserPermission(Binder.getCallingUid(), userId,
                false /* requireFullPermission */, false /* checkShell */,
                "query intent activities");
            //意图里的包名
        final String pkgName = intent.getPackage();
        Intent originalIntent = null;
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                originalIntent = intent;
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }

        flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
                comp != null || pkgName != null /*onlyExposedExplicitly*/,
                isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId, resolvedType,
                        flags));
        List<ResolveInfo> list = Collections.emptyList();
        boolean skipPostResolution = false;
        //意图里有指定的组件
        if (comp != null) {
            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
            if (ai != null) {
                final boolean matchInstantApp =
                        (flags & PackageManager.MATCH_INSTANT) != 0;
                final boolean matchVisibleToInstantAppOnly =
                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
                final boolean matchExplicitlyVisibleOnly =
                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
                final boolean isCallerInstantApp =
                        instantAppPkgName != null;
                final boolean isTargetSameInstantApp =
                        comp.getPackageName().equals(instantAppPkgName);
                final boolean isTargetInstantApp =
                        (ai.applicationInfo.privateFlags
                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                final boolean isTargetVisibleToInstantApp =
                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
                final boolean isTargetExplicitlyVisibleToInstantApp =
                        isTargetVisibleToInstantApp
                                && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP)
                                == 0;
                final boolean isTargetHiddenFromInstantApp =
                        !isTargetVisibleToInstantApp
                                || (matchExplicitlyVisibleOnly
                                && !isTargetExplicitlyVisibleToInstantApp);
                final boolean blockInstantResolution =
                        !isTargetSameInstantApp
                                && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                && isTargetHiddenFromInstantApp));
                final boolean blockNormalResolution =
                        !resolveForStart && !isTargetInstantApp && !isCallerInstantApp
                                && shouldFilterApplication(
                                getPackageStateInternal(ai.applicationInfo.packageName,
                                        Process.SYSTEM_UID), filterCallingUid, userId);
                if (!blockInstantResolution && !blockNormalResolution) {
                    final ResolveInfo ri = new ResolveInfo();
                    ri.activityInfo = ai;
                    list = new ArrayList<>(1);
                    list.add(ri);
                    PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                            mInjector.getCompatibility(), mComponentResolver,
                            list, false, intent, resolvedType, filterCallingUid);
                }
            }
        } else {
            QueryIntentActivitiesResult lockedResult =
                    queryIntentActivitiesInternalBody(
                            intent, resolvedType, flags, filterCallingUid, userId,
                            resolveForStart, allowDynamicSplits, pkgName, instantAppPkgName);
            if (lockedResult.answer != null) {
                skipPostResolution = true;
                list = lockedResult.answer;
            } else {
                if (lockedResult.addInstant) {
                    String callingPkgName = getInstantAppPackageName(filterCallingUid);
                    boolean isRequesterInstantApp = isInstantApp(callingPkgName, userId);
                    lockedResult.result = maybeAddInstantAppInstaller(
                            lockedResult.result, intent, resolvedType, flags,
                            userId, resolveForStart, isRequesterInstantApp);
                }
                if (lockedResult.sortResult) {
                    lockedResult.result.sort(RESOLVE_PRIORITY_SORTER);
                }
                list = lockedResult.result;
            }
        }

        if (originalIntent != null) {
            // We also have to ensure all components match the original intent
            PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                    mInjector.getCompatibility(), mComponentResolver,
                    list, false, originalIntent, resolvedType, filterCallingUid);
        }

        return skipPostResolution ? list : applyPostResolutionFilter(
                list, instantAppPkgName, allowDynamicSplits, filterCallingUid,
                resolveForStart, userId, intent);
    }

>1.queryIntentActivitiesInternalBody

    public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits,
            String pkgName, String instantAppPkgName) {
        // reader
        boolean sortResult = false;
        boolean addInstant = false;
        List<ResolveInfo> result = null;
        if (pkgName == null) {
        //参考补充2,获取已有的数据
            List<CrossProfileIntentFilter> matchingFilters =
                    getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
            //检查需要跳过当前配置文件的结果
            ResolveInfo skipProfileInfo  = querySkipCurrentProfileIntents(matchingFilters,
                    intent, resolvedType, flags, userId);
            if (skipProfileInfo != null) {
                List<ResolveInfo> xpResult = new ArrayList<>(1);
                xpResult.add(skipProfileInfo);
                return new QueryIntentActivitiesResult(
                        applyPostResolutionFilter(
                                filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
                                allowDynamicSplits, filterCallingUid, resolveForStart, userId,
                                intent));
            }

            //检查当前配置文件中的结果
            result = filterIfNotSystemUser(mComponentResolver.queryActivities(this,
                    intent, resolvedType, flags, userId), userId);
            addInstant = isInstantAppResolutionAllowed(intent, result, userId,
                    false /*skipPackageCheck*/, flags);
            // 是否有非负的优先级的结果
            boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
            CrossProfileDomainInfo specificXpInfo = queryCrossProfileIntents(
                    matchingFilters, intent, resolvedType, flags, userId,
                    hasNonNegativePriorityResult);
            if (intent.hasWebURI()) {
//...
            } else {
                // 不是web意图的,加入集合即可
                if (specificXpInfo != null) {
                    result.add(specificXpInfo.mResolveInfo);
                    sortResult = true;
                }
            }
        } else {
//..
        }
        return new QueryIntentActivitiesResult(sortResult, addInstant, result);
    }

>2.getMatchingCrossProfileIntentFilters

    public final List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
            Intent intent, String resolvedType, int userId) {
        CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId);
        if (resolver != null) {
            return resolver.queryIntent(this, intent, resolvedType, false /*defaultOnly*/, userId);
        }
        return null;
    }

3.8.canViewInstantApps

这个调用的地方有点多

    public final boolean canViewInstantApps(int callingUid, int userId) {
        if (callingUid < Process.FIRST_APPLICATION_UID) {
            return true;
        }
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
            return true;
        }
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
                //补充1
            final ComponentName homeComponent = getDefaultHomeActivity(userId);
            if (homeComponent != null
                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
                return true;
            }
            return mAppPredictionServicePackage != null
                    && isCallerSameApp(mAppPredictionServicePackage, callingUid);
        }
        return false;
    }

>1.getDefaultHomeActivity

  • 获取默认的桌面组件
    public final ComponentName getDefaultHomeActivity(int userId) {
        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
        //补充2
        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
        if (cn != null) {
            return cn;
        }
        //为空,就从allHomeCandidates里边找到优先级最高的那个返回
        int lastPriority = Integer.MIN_VALUE;
        ComponentName lastComponent = null;
        final int size = allHomeCandidates.size();
        for (int i = 0; i < size; i++) {
            final ResolveInfo ri = allHomeCandidates.get(i);
            if (ri.priority > lastPriority) {
                lastComponent = ri.activityInfo.getComponentName();
                lastPriority = ri.priority;
            } else if (ri.priority == lastPriority) {
                //两个优先级一样的,则置空
                lastComponent = null;
            }
        }
        return lastComponent;
    }

>2.getHomeActivitiesAsUser

    public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
    //..补充3
        PackageManagerService.FindPreferredActivityBodyResult result =
                findPreferredActivityInternal(intent, null, 0, resolveInfos, true, false,
                        false, userId, filtered);

>3.findPreferredActivityInternal

    public final PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
//..补充4
        return findPreferredActivityBody(
                intent, resolvedType, flags, query, always, removeMatches, debug,
                userId, queryMayBeFiltered, callingUid, isDeviceProvisioned);
    }

>4.findPreferredActivityBody

    protected PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityBody(
//..
        //先找持久化的,就是对应意图的偏好也就是默认的
        result.mPreferredResolveInfo = findPersistentPreferredActivity(intent,
                resolvedType, flags, query, debug, userId);
        // 找到了就用它
        if (result.mPreferredResolveInfo != null) {
            return result;
        }

        PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
        //继续找
        List<PreferredActivity> prefs = pir != null
                ? pir.queryIntent(this, intent, resolvedType,
                (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
                userId)
                : null;                

4.ModuleInfoProvider.java

    /**
     * The key in the package's application level metadata bundle that provides a resource reference
     * to the module metadata.
     */
    private static final String MODULE_METADATA_KEY = "android.content.pm.MODULE_METADATA";

4.1.systemReady

这个方法在PMS的同名方法里会被调用

    public void systemReady() {
    //数据见补充1
        mPackageName = mContext.getResources().getString(
                R.string.config_defaultModuleMetadataProvider);
        if (TextUtils.isEmpty(mPackageName)) {
            Slog.w(TAG, "No configured module metadata provider.");
            return;
        }

        final Resources packageResources;
        final PackageInfo pi;
        try {
        //根据配置的包名,获取包的packageInfo
            pi =  getPackageManager().getPackageInfo(mPackageName,
                PackageManager.GET_META_DATA, UserHandle.USER_SYSTEM);

            Context packageContext = mContext.createPackageContext(mPackageName, 0);
            packageResources = packageContext.getResources();
        } catch (RemoteException | NameNotFoundException e) {
            return;
        }
        //解析meta-data里MODULE_METADATA_KEY对应的资源文件
        XmlResourceParser parser = packageResources.getXml(
                pi.applicationInfo.metaData.getInt(MODULE_METADATA_KEY));
        loadModuleMetadata(parser, packageResources);//参考4.2
    }

>1.config_defaultModuleMetadataProvider

    <!-- Component name for the default module metadata provider on this device -->
    <string name="config_defaultModuleMetadataProvider"
    translatable="false">com.android.modulemetadata</string>

>2.清单文件

源码的packages/modules/ModuleMetadata目录下

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.modulemetadata">
    <application android:name=".ModuleMetadataApplication"
                 android:label="@string/app_name">
        <meta-data android:name="android.content.pm.MODULE_METADATA"
                   android:resource="@xml/module_metadata" />
    </application>
</manifest>

我看了一下上边的module_metadata.xml文件,里边默认是没有module数据的。

>3.demo数据

<module-metadata>
  <module name="@string/module_1_name" packageName="com.android.module1" isHidden="false" />
  <module name="@string/module_2_name" packageName="com.android.module2" isHidden="true"/>
</module-metadata>

4.2.loadModuleMetadata

这个就是解析xml文件,下边注解里有xml的格式,非常简单。参考4.1.3

    private void loadModuleMetadata(XmlResourceParser parser, Resources packageResources) {
        try {
            // The format for the module metadata is straightforward :
            //
            // The following attributes on <module> are currently defined :
            // -- name : A resource reference to a User visible package name, maps to
            //           ModuleInfo#getName
            // -- packageName : The package name of the module, see ModuleInfo#getPackageName
            // -- isHidden : Whether the module is hidden, see ModuleInfo#isHidden
            //
            // <module-metadata>
            //   <module name="@string/resource" packageName="package_name" isHidden="false|true" />
            //   <module .... />
            // </module-metadata>

            XmlUtils.beginDocument(parser, "module-metadata");
            while (true) {
                XmlUtils.nextElement(parser);
                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
                    break;
                }

                if (!"module".equals(parser.getName())) {
                    //不是module标签,说明数据异常,清空数据
                    mModuleInfo.clear();
                    break;
                }
                //解析对应的字段
                final CharSequence moduleName = packageResources.getText(
                        Integer.parseInt(parser.getAttributeValue(null, "name").substring(1)));
                final String modulePackageName = XmlUtils.readStringAttribute(parser,
                        "packageName");
                final boolean isHidden = XmlUtils.readBooleanAttribute(parser, "isHidden");

                ModuleInfo mi = new ModuleInfo();
                mi.setHidden(isHidden);
                mi.setPackageName(modulePackageName);
                mi.setName(moduleName);
                mi.setApexModuleName(
                        mApexManager.getApexModuleNameForPackageName(modulePackageName));
                //放入集合
                mModuleInfo.put(modulePackageName, mi);
            }
        } catch (XmlPullParserException | IOException e) {
            mModuleInfo.clear();
        } finally {
            parser.close();
            mMetadataLoaded = true;
        }
    }

4.3.getInstalledModules

    List<ModuleInfo> getInstalledModules(@PackageManager.InstalledModulesFlags int flags) {
        if (!mMetadataLoaded) {
            throw new IllegalStateException("Call to getInstalledModules before metadata loaded");
        }
        //flags是match_all,返回所有数据
        if ((flags & PackageManager.MATCH_ALL) != 0) {
            return new ArrayList<>(mModuleInfo.values());
        }

        List<PackageInfo> allPackages;
        //根据flags,获取所有已安装的包信息
        try {
            allPackages =  getPackageManager().getInstalledPackages(
                    flags | PackageManager.MATCH_APEX, UserHandle.getCallingUserId()).getList();
        } catch (RemoteException e) {
            Slog.w(TAG, "Unable to retrieve all package names", e);
            return Collections.emptyList();
        }

        ArrayList<ModuleInfo> installedModules = new ArrayList<>(allPackages.size());
        for (PackageInfo p : allPackages) {
        //根据包名过滤集合
            ModuleInfo m = mModuleInfo.get(p.packageName);
            if (m != null) {
                installedModules.add(m);
            }
        }
        return installedModules;
    }

4.4.getModuleInfo

根据名字查找moduleInfo,flags就用来匹配APEX module name

    ModuleInfo getModuleInfo(String name, @PackageManager.ModuleInfoFlags int flags) {
        if (!mMetadataLoaded) {
            throw new IllegalStateException("Call to getModuleInfo before metadata loaded");
        }
        if ((flags & PackageManager.MODULE_APEX_NAME) != 0) {
            for (ModuleInfo moduleInfo : mModuleInfo.values()) {
                if (name.equals(moduleInfo.getApexModuleName())) {
                    return moduleInfo;
                }
            }
            return null;
        }
        return mModuleInfo.get(name);
    }

5.SigningDetails

5.1.构造方法

    public SigningDetails(@Nullable Signature[] signatures,
            @SignatureSchemeVersion int signatureSchemeVersion,
            @Nullable Signature[] pastSigningCertificates)
            throws CertificateException {
        this(signatures, signatureSchemeVersion, toSigningKeys(signatures),
                pastSigningCertificates);
    }

>1.SignatureSchemeVersion

签名方案的版本,只记得2和3,啥时候4都出来了

    @IntDef({SignatureSchemeVersion.UNKNOWN,
            SignatureSchemeVersion.JAR,
            SignatureSchemeVersion.SIGNING_BLOCK_V2,
            SignatureSchemeVersion.SIGNING_BLOCK_V3,
            SignatureSchemeVersion.SIGNING_BLOCK_V4})
    public @interface SignatureSchemeVersion {
        int UNKNOWN = 0;
        int JAR = 1;
        int SIGNING_BLOCK_V2 = 2;
        int SIGNING_BLOCK_V3 = 3;
        int SIGNING_BLOCK_V4 = 4;
    }

>2.toSigningKeys

    public static ArraySet<PublicKey> toSigningKeys(@NonNull Signature[] signatures)
            throws CertificateException {
        final ArraySet<PublicKey> keys = new ArraySet<>(signatures.length);
        for (int i = 0; i < signatures.length; i++) {
            keys.add(signatures[i].getPublicKey());
        }
        return keys;
    }

6.Signature.java

6.1.构造方法

public class Signature implements Parcelable {
    private final byte[] mSignature;
    private int mHashCode;
    private boolean mHaveHashCode;
    private SoftReference<String> mStringRef;
    private Certificate[] mCertificateChain;

>1.构造方法

    public Signature(byte[] signature) {
        mSignature = signature.clone();
        mCertificateChain = null;
    }

>2.构造方法2

     * @param text hex-encoded string representing the signature
     * @throws IllegalArgumentException when signature is odd-length
     */
    public Signature(String text) {
        final byte[] input = text.getBytes();
        final int N = input.length;

        if (N % 2 != 0) {
            throw new IllegalArgumentException("text size " + N + " is not even");
        }

        final byte[] sig = new byte[N / 2];
        int sigIndex = 0;

        for (int i = 0; i < N;) {
            final int hi = parseHexDigit(input[i++]);
            final int lo = parseHexDigit(input[i++]);
            sig[sigIndex++] = (byte) ((hi << 4) | lo);
        }

        mSignature = sig;
    }

这里和wifi那边差不多

    private static final int parseHexDigit(int nibble) {
        if ('0' <= nibble && nibble <= '9') {
            return nibble - '0';
        } else if ('a' <= nibble && nibble <= 'f') {
            return nibble - 'a' + 10;
        } else if ('A' <= nibble && nibble <= 'F') {
            return nibble - 'A' + 10;
        } else {
            throw new IllegalArgumentException("Invalid character " + nibble + " in hex string");
        }
    }

6.2.比较

可以看到,就比较mSignature这个byte数组

    public boolean equals(@Nullable Object obj) {
        try {
            if (obj != null) {
                Signature other = (Signature)obj;
                // Note, some classes, such as SigningDetails, rely on equals
                // only comparing the mSignature arrays without the flags.
                return this == other || Arrays.equals(mSignature, other.mSignature);
            }
        } catch (ClassCastException e) {
        }
        return false;
    }

    @Override
    public int hashCode() {
        if (mHaveHashCode) {
            return mHashCode;
        }
        // Note, similar to equals some classes rely on the hash code not including
        // the flags for Set membership checks.
        mHashCode = Arrays.hashCode(mSignature);
        mHaveHashCode = true;
        return mHashCode;
    }

6.3.getPublicKey

    public PublicKey getPublicKey() throws CertificateException {
        final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        final ByteArrayInputStream bais = new ByteArrayInputStream(mSignature);
        final Certificate cert = certFactory.generateCertificate(bais);
        return cert.getPublicKey();
    }

7.小节2.6补充

7.1.PreferredActivityHelper.java

>1.addPreferredActivity

    public void addPreferredActivity(@NonNull Computer snapshot, WatchedIntentFilter filter,
            int match, ComponentName[] set, ComponentName activity, boolean always, int userId,
            String opname, boolean removeExisting) {
//权限检查,代码省略
        if (filter.countActions() == 0) {
            return;
        }

        synchronized (mPm.mLock) {
            final PreferredIntentResolver pir = mPm.mSettings.editPreferredActivitiesLPw(userId);
            final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
            if (removeExisting && existing != null) {
                Settings.removeFilters(pir, filter, existing);
            }
            pir.addFilter(mPm.snapshotComputer(),
                    new PreferredActivity(filter, match, set, activity, always));
            mPm.scheduleWritePackageRestrictions(userId);
        }
        //补充2,补充3
        if (!(isHomeFilter(filter) && updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId))) {//非桌面意图或者更新默认桌面失败,则发送 preferred activity改变广播
            mPm.postPreferredActivityChangedBroadcast(userId);
        }
    }

>2.isHomeFilter

桌面过滤器条件

    private boolean isHomeFilter(@NonNull WatchedIntentFilter filter) {
        return filter.hasAction(Intent.ACTION_MAIN) && filter.hasCategory(Intent.CATEGORY_HOME)
                && filter.hasCategory(CATEGORY_DEFAULT);
    }

>3.updateDefaultHomeNotLocked

    public boolean updateDefaultHomeNotLocked(@NonNull Computer snapshot, @UserIdInt int userId) {
        if (!mPm.isSystemReady()) {
            return false;
        }
        final Intent intent = snapshot.getHomeIntent();
        //参考3.7,查找对应意图的活动集合
        final List<ResolveInfo> resolveInfos = snapshot.queryIntentActivitiesInternal(
                intent, null, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
                //补充4
        final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(snapshot,
                intent, null, 0, resolveInfos, true, false, false, userId);
        final String packageName = preferredResolveInfo != null
                && preferredResolveInfo.activityInfo != null
                ? preferredResolveInfo.activityInfo.packageName : null;
         //通过RoleManager获取默认的桌面
        final String currentPackageName = mPm.getActiveLauncherPackageName(userId);
        两种一样,不用处理了
        if (TextUtils.equals(currentPackageName, packageName)) {
            return false;
        }
        final String[] callingPackages = snapshot.getPackagesForUid(Binder.getCallingUid());
        if (callingPackages != null && ArrayUtils.contains(callingPackages,
                mPm.mRequiredPermissionControllerPackage)) {
//调用者里有权限管理包
            return false;
        }

        if (packageName == null) {
            return false;
        }
        //参考8.1,利用roleManager设置默认的桌面
        return mPm.setActiveLauncherPackage(packageName, userId,
                successful -> {
                    if (successful) {
                        mPm.postPreferredActivityChangedBroadcast(userId);
                    }
                });
    }

>4.findPreferredActivityNotLocked

找到对应Intent的首选活动信息,交给Computer处理了

    public ResolveInfo findPreferredActivityNotLocked(@NonNull Computer snapshot,
            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug,
            int userId, boolean queryMayBeFiltered) {

        if (!mPm.mUserManager.exists(userId)) return null;

        PackageManagerService.FindPreferredActivityBodyResult body =
        //参考3.6.1
                snapshot.findPreferredActivityInternal(
                intent, resolvedType, flags, query, always,
                removeMatches, debug, userId, queryMayBeFiltered);
        if (body.mChanged) {
            mPm.scheduleWritePackageRestrictions(userId);
        }

        return body.mPreferredResolveInfo;
    }

7.2.PreferredActivity

>1.构造方法

    PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity,
            boolean always) {
        super(filter);
        mPref = new PreferredComponent(this, match, set, activity, always);
        mSnapshot = makeCache();
    }

7.3.PreferredComponent

>1.sameSet

引导包特殊处理,否则自己的mSetPackages数据要和query一样。

    public boolean sameSet(List<ResolveInfo> query, boolean excludeSetupWizardPackage, int userId) {
        if (mSetPackages == null) {
            return query == null;
        }
        if (query == null) {
            return false;
        }
        final int NQ = query.size();
        final int NS = mSetPackages.length;
        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
        String setupWizardPackageName = pmi.getSetupWizardPackageName();
        int numMatch = 0;
        //循环所有的查询结果
        for (int i=0; i<NQ; i++) {
            ResolveInfo ri = query.get(i);
            ActivityInfo ai = ri.activityInfo;
            boolean good = false;

            //忽略引导包
            if (excludeSetupWizardPackage && ai.packageName.equals(setupWizardPackageName)) {
                continue;
            }
//忽略安装原因是setup的包
            final PackageUserState pkgUserState =
                    pmi.getPackageStateInternal(ai.packageName).getUserStates().get(userId);
            if (pkgUserState != null && pkgUserState.getInstallReason()
                    == PackageManager.INSTALL_REASON_DEVICE_SETUP) {
                continue;
            }
//循环自己的集合
            for (int j=0; j<NS; j++) {
            //包名,类名一样,说明匹配
                if (mSetPackages[j].equals(ai.packageName)
                        && mSetClasses[j].equals(ai.name)) {
                    numMatch++;
                    good = true;
                    break;
                }
            }
            //没找到一样的,说明要查询的和自己的集合数据不一样
            if (!good) return false;
        }
        return numMatch == NS;
    }

>2.isSuperset

也就是query里的信息都在自己的mSetPackages集合里,引导包特殊处理。

    public boolean isSuperset(List<ResolveInfo> query, boolean excludeSetupWizardPackage) {
        if (mSetPackages == null) {
            return query == null;
        }
        if (query == null) {
            return true;
        }
        final int NQ = query.size();
        final int NS = mSetPackages.length;
        //不排除引导包,自己的数据比要比较的数据还少,
        if (!excludeSetupWizardPackage && NS < NQ) {
            return false;
        }
        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
        String setupWizardPackageName = pmi.getSetupWizardPackageName();
        for (int i=0; i<NQ; i++) {
            ResolveInfo ri = query.get(i);
            ActivityInfo ai = ri.activityInfo;
            boolean foundMatch = false;

            //
            if (excludeSetupWizardPackage && ai.packageName.equals(setupWizardPackageName)) {
                continue;
            }

            for (int j=0; j<NS; j++) {
                if (mSetPackages[j].equals(ai.packageName) && mSetClasses[j].equals(ai.name)) {
                    foundMatch = true;
                    break;
                }
            }
            if (!foundMatch) return false;
        }
        return true;
    }

8.PackageManagerService.java

8.1.setActiveLauncherPackage

    boolean setActiveLauncherPackage(@NonNull String packageName, @UserIdInt int userId,
            @NonNull Consumer<Boolean> callback) {
            //参考8.2.1
        return mDefaultAppProvider.setDefaultHome(packageName, userId, mContext.getMainExecutor(),
                callback);
    }

>1.mDefaultAppProvider

                (i, pm) -> new DefaultAppProvider(() -> context.getSystemService(RoleManager.class),
                        () -> LocalServices.getService(UserManagerInternal.class)),

8.2.DefaultAppProvider

>1.setDefaultHome

    public boolean setDefaultHome(@NonNull String packageName, @UserIdInt int userId,
            @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
        final RoleManager roleManager = mRoleManagerSupplier.get();
        if (roleManager == null) {
            return false;
        }

        try {
            roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, packageName, 0,
                    UserHandle.of(userId), executor, callback);
        }
        return true;
    }

8.3.restorePermissionsAndUpdateRolesForNewUserInstall

    void restorePermissionsAndUpdateRolesForNewUserInstall(String packageName,
            @UserIdInt int userId) {
//如果有备份的权限需要恢复的话,进行处理。
//比如我们备份test.apk的权限,恢复的时候还没安装,那么等它安装后这里就会恢复其权限
        mPermissionManager.restoreDelayedRuntimePermissions(packageName, userId);

        //参考7.1.3,更新默认的桌面
        mPreferredActivityHelper.updateDefaultHomeNotLocked(snapshotComputer(), userId);
    }

8.4.notifyInstallObserver

    void notifyInstallObserver(PackageInstalledInfo info,
            IPackageInstallObserver2 installObserver) {
        if (installObserver != null) {
            try {
                Bundle extras = extrasForInstallResult(info);
                //这里处理完最终又回调补充1
                installObserver.onPackageInstalled(info.mName, info.mReturnCode,
                        info.mReturnMsg, extras);
            } 
        }
    }

>1.sendSessionCommitBroadcast

    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
        UserManagerService ums = UserManagerService.getInstance();
        if (ums == null || sessionInfo.isStaged()) {
            return;
        }
        final UserInfo parent = ums.getProfileParent(userId);
        final int launcherUid = (parent != null) ? parent.id : userId;
//获取默认的桌面组件
        final ComponentName launcherComponent = snapshotComputer()
                .getDefaultHomeActivity(launcherUid);
                //发送包安装完成的广播给桌面应用
        mBroadcastHelper.sendSessionCommitBroadcast(sessionInfo, userId, launcherUid,
                launcherComponent, mAppPredictionServicePackage);
    }

9.InstallPackageHelper

9.1.安装一个新的app

这里整理下流程

  • 补充2到5是安装应用
  • 补充6到10是安装后的操作,最终走到9.2

>1.processInstallRequests

    public void processInstallRequests(boolean success, List<InstallRequest> installRequests) {
    //..
        if (success) {
            for (InstallRequest request : apkInstallRequests) {
                request.mArgs.doPreInstall(request.mInstallResult.mReturnCode);
            }
            synchronized (mPm.mInstallLock) {
                installPackagesTracedLI(apkInstallRequests);//补充2
            }
//..上边已经安装完了,这里是安装后的处理操作

        for (InstallRequest request : apkInstallRequests) {
        //补充6
            restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
                    request.mInstallResult,
                    new PostInstallData(request.mArgs,
                            request.mInstallResult, null));
        }
    }

>2.installPackagesTracedLI

    private void installPackagesTracedLI(List<InstallRequest> requests) {
        try {
            installPackagesLI(requests);//补充3
        }
    }

>3.installPackagesLI

    private void installPackagesLI(List<InstallRequest> requests) {
    //...
                try {
                    commitRequest = new CommitRequest(reconciledPackages,
                            mPm.mUserManager.getUserIds());
                    commitPackagesLocked(commitRequest);//补充4
                    success = true;

>4.commitPackagesLocked

    private void commitPackagesLocked(final CommitRequest request) {

//..
            AndroidPackage pkg = commitReconciledScanResultLocked(
                    reconciledPkg, request.mAllUsers);
                    //补充5
            updateSettingsLI(pkg, reconciledPkg, request.mAllUsers, res);

>5.updateSettingsInternalLI

    private void updateSettingsLI(AndroidPackage newPackage, ReconciledPackage reconciledPkg,
            int[] allUsers, PackageInstalledInfo res) {
        updateSettingsInternalLI(newPackage, reconciledPkg, allUsers, res);
    }
    
    private void updateSettingsInternalLI(AndroidPackage pkg, ReconciledPackage reconciledPkg,
            int[] allUsers, PackageInstalledInfo res) {

>6.restoreAndPostInstall

    public void restoreAndPostInstall(
            int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
    //是否是更新操作:需要移除的包不为空
        final boolean update = res.mRemovedInfo != null
                && res.mRemovedInfo.mRemovedPackage != null;
      // 是否需要restore取决两个条件:(a)安装成功, (b) 非更新操作
        boolean doRestore = !update && res.mPkg != null;
//..
        if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
            if (res.mFreezer != null) {
                res.mFreezer.close();
            }
            doRestore = performBackupManagerRestore(userId, token, res);//补充7
        }

>7.performBackupManagerRestore

    private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
    //
            try {
                if (iBackupManager.isUserReadyForBackup(userId)) {
                //补充8
                    iBackupManager.restoreAtInstallForUser(
                            userId, res.mPkg.getPackageName(), token);
                } else {       

>8.restoreAtInstallForUser

BackupManagerService.java

    public void restoreAtInstallForUser(int userId, String packageName, int token)
            throws RemoteException {
        if (isUserReadyForBackup(userId)) {
            restoreAtInstall(userId, packageName, token);
        }
    }
    private final IPackageManager mPackageManagerBinder;
    public void restoreAtInstall(String packageName, int token) {
//...

            try {//补充9
                mPackageManagerBinder.finishPackageInstall(token, false);
            } catch (RemoteException e) { /* can't happen */ }
        }
    }

>9.finishPackageInstall

PackageManagerService.java

    void finishPackageInstall(int token, boolean didLaunch) {
//补充10
        final Message msg = mHandler.obtainMessage(PackageManagerService.POST_INSTALL, token,
                didLaunch ? 1 : 0);
        mHandler.sendMessage(msg);
    }

这里看下handler是啥

                (i, pm) -> {
                    HandlerThread thread = new ServiceThread(TAG,
                            Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
                    thread.start();
                    return new PackageHandler(thread.getLooper(), pm);
                },

>10.PackageHandler

final class PackageHandler extends Handler {
            case POST_INSTALL: {

                PostInstallData data = mPm.mRunningInstalls.get(msg.arg1);
                final boolean didRestore = (msg.arg2 != 0);
                mPm.mRunningInstalls.delete(msg.arg1);

                if (data != null && data.res.mFreezer != null) {
                    data.res.mFreezer.close();
                }

                if (data != null && data.mPostInstallRunnable != null) {
                    data.mPostInstallRunnable.run();
                } else if (data != null && data.args != null) {
                //这里就走到9.2了
                    mInstallPackageHelper.handlePackagePostInstall(data.res, data.args, didRestore);
                }
            } break;

>11.日志

  • PackageHandler里处理msg:POST_INSTALL,里边会调用InstallPackageHelper的handlePackagePostInstall方法
  • 参考9.1
at com.android.server.pm.PreferredActivityHelper.updateDefaultHomeNotLocked(PreferredActivityHelper.java:139)
at com.android.server.pm.PackageManagerService.restorePermissionsAndUpdateRolesForNewUserInstall(PackageManagerService.java:3444)
at com.android.server.pm.InstallPackageHelper.handlePackagePostInstall(InstallPackageHelper.java:2917)
at com.android.server.pm.PackageHandler.doHandleMessage(PackageHandler.java:114)
at com.android.server.pm.PackageHandler.handleMessage(PackageHandler.java:76)

9.2.handlePackagePostInstall

包安装完成后会走这里。

    void handlePackagePostInstall(PackageInstalledInfo res, InstallArgs installArgs,
            boolean launchedForRestore) {
        final boolean killApp =
                (installArgs.mInstallFlags & PackageManager.INSTALL_DONT_KILL_APP) == 0;
        final boolean virtualPreload =
                ((installArgs.mInstallFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
        final String installerPackage = installArgs.mInstallSource.installerPackageName;
        final IPackageInstallObserver2 installObserver = installArgs.mObserver;
        final int dataLoaderType = installArgs.mDataLoaderType;
        //是否安装成功
        final boolean succeeded = res.mReturnCode == PackageManager.INSTALL_SUCCEEDED;
        final boolean update = res.mRemovedInfo != null && res.mRemovedInfo.mRemovedPackage != null;
        final String packageName = res.mName;
        final PackageStateInternal pkgSetting =
                succeeded ? mPm.snapshotComputer().getPackageStateInternal(packageName) : null;
        //状态为空,或者 系统应用并且安装包位置变化,则认为需要在更新前移除
        final boolean removedBeforeUpdate = (pkgSetting == null)
                || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals(
                res.mPkg.getPath()));
        if (succeeded && removedBeforeUpdate) {

            res.mReturnCode = INSTALL_FAILED_PACKAGE_CHANGED;
            res.mReturnMsg = "Package was removed before install could complete.";

            InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
            if (args != null) {
                synchronized (mPm.mInstallLock) {
                    args.doPostDeleteLI(true);
                }
            }
            mPm.notifyInstallObserver(res, installObserver);
            return;
        }

        if (succeeded) {
            //在安装新包后清除uid缓存
            mPm.mPerUidReadTimeoutsCache = null;
            //发送旧包移除广播
            if (res.mRemovedInfo != null) {
                if (res.mRemovedInfo.mIsExternal) {

                    final int[] uidArray = new int[]{res.mRemovedInfo.mUid};
                    final ArrayList<String> pkgList = new ArrayList<>(1);
                    pkgList.add(res.mRemovedInfo.mRemovedPackage);
                    //发送广播,对应的包不可用,补充1
                    mBroadcastHelper.sendResourcesChangedBroadcast(
                            false, true, pkgList, uidArray, null);
                }
                res.mRemovedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
            }

            final String installerPackageName =
                    res.mInstallerPackageName != null
                            ? res.mInstallerPackageName
                            : res.mRemovedInfo != null
                                    ? res.mRemovedInfo.mInstallerPackageName
                                    : null;

            mPm.notifyInstantAppPackageInstalled(res.mPkg.getPackageName(), res.mNewUsers);

            int[] firstUserIds = EMPTY_INT_ARRAY;
            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
            int[] updateUserIds = EMPTY_INT_ARRAY;
            int[] instantUserIds = EMPTY_INT_ARRAY;
            //这个一般是true
            final boolean allNewUsers = res.mOrigUsers == null || res.mOrigUsers.length == 0;
            for (int newUser : res.mNewUsers) {
                final boolean isInstantApp = pkgSetting.getUserStateOrDefault(newUser)
                        .isInstantApp();
                if (allNewUsers) {
                    if (isInstantApp) {
                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
                    } else {//正常走这里
                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
                    }
                    continue;
                }
                boolean isNew = true;
                for (int origUser : res.mOrigUsers) {
                    if (origUser == newUser) {
                        isNew = false;
                        break;
                    }
                }
                if (isNew) {
                    if (isInstantApp) {
                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
                    } else {
                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
                    }
                } else {
                    if (isInstantApp) {
                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
                    } else {
                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
                    }
                }
            }

            //如果包不是静态共享库,则发送已安装的广播。
            if (res.mPkg.getStaticSharedLibName() == null) {
                mPm.mProcessLoggingHandler.invalidateBaseApkHash(res.mPkg.getBaseApkPath());

                int appId = UserHandle.getAppId(res.mUid);
                boolean isSystem = res.mPkg.isSystem();
                //发送包添加的广播,为第一次看到包的用户添加发送
                mPm.sendPackageAddedForNewUsers(mPm.snapshotComputer(), packageName,
                        isSystem || virtualPreload, virtualPreload /*startReceiver*/, appId,
                        firstUserIds, firstInstantUserIds, dataLoaderType);


                Bundle extras = new Bundle();
                extras.putInt(Intent.EXTRA_UID, res.mUid);
                if (update) {
                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
                }
                extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
                // 发送到所有运行的应用程序
                final SparseArray<int[]> newBroadcastAllowList;
                synchronized (mPm.mLock) {
                    final Computer snapshot = mPm.snapshotComputer();
                    newBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(snapshot,
                            snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID),
                            updateUserIds, mPm.mSettings.getPackagesLocked());
                }
                //这里感觉又发送一次?
                mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                        extras, 0 /*flags*/,
                        null /*targetPackage*/, null /*finishedReceiver*/,
                        updateUserIds, instantUserIds, newBroadcastAllowList, null);
                if (installerPackageName != null) {
                    // 发送广播到包安装程序,即使它没有运行。
                    mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                            extras, 0 /*flags*/,
                            installerPackageName, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
                }

                //如果需要验证者,并且和安装包不一样,那么给对应的包发送广播
                final boolean notifyVerifier = mPm.mRequiredVerifierPackage != null
                        && !mPm.mRequiredVerifierPackage.equals(installerPackageName);
                if (notifyVerifier) {
                    mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                            extras, 0 /*flags*/,
                            mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
                }
                //如果指定了包的安装程序,发送对应的广播给它
                if (mPm.mRequiredInstallerPackage != null) {
                    mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                            extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
                            mPm.mRequiredInstallerPackage, null /*finishedReceiver*/,
                            firstUserIds, instantUserIds, null /* broadcastAllowList */, null);
                }

                // 对于第一次没有看到包的用户,发送替换广播
                if (update) {
                    mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                            packageName, extras, 0 /*flags*/,
                            null /*targetPackage*/, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds, res.mRemovedInfo.mBroadcastAllowList,
                            null);
                    if (installerPackageName != null) {
                        mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                extras, 0 /*flags*/,
                                installerPackageName, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds, null /*broadcastAllowList*/,
                                null);
                    }
                    if (notifyVerifier) {
                        mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                extras, 0 /*flags*/,
                                mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds, null /*broadcastAllowList*/,
                                null);
                    }
                    mPm.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                            null /*package*/, null /*extras*/, 0 /*flags*/,
                            packageName /*targetPackage*/,
                            null /*finishedReceiver*/, updateUserIds, instantUserIds,
                            null /*broadcastAllowList*/,
                            mBroadcastHelper.getTemporaryAppAllowlistBroadcastOptions(
                                    REASON_PACKAGE_REPLACED).toBundle());
                } else if (launchedForRestore && !res.mPkg.isSystem()) {
                    //发送首次启动广播给安装程序
                    mBroadcastHelper.sendFirstLaunchBroadcast(packageName, installerPackage,
                            firstUserIds, firstInstantUserIds);
                }

                //包安装在外部存储卡上的
                if (res.mPkg.isExternalStorage()) {
                    if (!update) {
                        final StorageManager storageManager =
                                mInjector.getSystemService(StorageManager.class);
                        VolumeInfo volume =
                                storageManager.findVolumeByUuid(
                                        StorageManager.convert(
                                                res.mPkg.getVolumeUuid()).toString());
                        int packageExternalStorageType =
                                PackageManagerServiceUtils.getPackageExternalStorageType(volume,
                                        res.mPkg.isExternalStorage());

                    }
                    final int[] uidArray = new int[]{res.mPkg.getUid()};
                    ArrayList<String> pkgList = new ArrayList<>(1);
                    pkgList.add(packageName);
                    //发送外置卡应用可用广播:Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
                    mBroadcastHelper.sendResourcesChangedBroadcast(
                            true, true, pkgList, uidArray, null);
                }
            } else if (!ArrayUtils.isEmpty(res.mLibraryConsumers)) { 
                // 如果是安装新版本的静态共享库,则无需杀死消费者
                final Computer snapshot = mPm.snapshotComputer();
                final boolean dontKillApp = !update && res.mPkg.getStaticSharedLibName() != null;
                for (int i = 0; i < res.mLibraryConsumers.size(); i++) {
                    AndroidPackage pkg = res.mLibraryConsumers.get(i);
                    //发送Intent.ACTION_PACKAGE_CHANGED
                    mPm.sendPackageChangedBroadcast(snapshot, pkg.getPackageName(), dontKillApp,
                            new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                            pkg.getUid(), null);
                }
            }

            // 需要在每个用户的首次安装时进行的工作
            if (firstUserIds.length > 0) {
                for (int userId : firstUserIds) {
                //参考8.3
                    mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
                            userId);
                }
            }

            if (allNewUsers && !update) {
                mPm.notifyPackageAdded(packageName, res.mUid);
            } else {
                mPm.notifyPackageChanged(packageName, res.mUid);
            }

            // 现在就安全地删除被替换包的旧资源
            InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
            if (args != null) {
                if (!killApp) {
                    //如果不需要杀死应用,那么延迟处理删除操作,以防仍在使用中
                    mPm.scheduleDeferredNoKillPostDelete(args);
                } else {
                    synchronized (mPm.mInstallLock) {
                        args.doPostDeleteLI(true);
                    }
                }
            } else {
                //
                VMRuntime.getRuntime().requestConcurrentGC();
            }

            final Computer snapshot = mPm.snapshotComputer();
            for (int userId : firstUserIds) {
                PackageInfo info = snapshot.getPackageInfo(packageName, /*flags*/ 0, userId);
                if (info != null) {
                    mDexManager.notifyPackageInstalled(info, userId);
                }
            }
        }

        final boolean deferInstallObserver = succeeded && update;
        if (deferInstallObserver) {
            if (killApp) {
                mPm.scheduleDeferredPendingKillInstallObserver(res, installObserver);
            } else {
                mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
            }
        } else {
            mPm.notifyInstallObserver(res, installObserver);
        }

        //删除已缓存一段时间的未使用的静态共享库
        mPm.schedulePruneUnusedStaticSharedLibraries(true /* delay */);

    }

>1.sendResourcesChangedBroadcast

    public void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
            String[] pkgList, int[] uidArr, IIntentReceiver finishedReceiver) {
        int size = pkgList.length;
        if (size > 0) {
            Bundle extras = new Bundle();
            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
            if (uidArr != null) {
                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
            }
            if (replacing) {
                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
            }
            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver,
                    null, null, null, null);
        }
    }

我们这里mediaStatus是false

  • 广播动作:一组之前可用的包,现在不可用了,因为它们存在的媒体不可用了。
  • 额外数据EXTRA_CHANGED_PACKAGE_LIST包含可用性发生变化的包的列表。集合里的包不接收此广播
  • 额外数据EXTRA_CHANGED_UID_LIST包含可用性发生变化的包的uid列表。
  • 比如,应用安装在外置卡上,然后把卡拔掉
public static final String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE =
    "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
  • 广播动作:一组之前不可用的包,现在是可用的,因为它们存在的媒体可用了。
  • EXTRA_CHANGED_PACKAGE_LIST包含可用性发生变化的包的列表。此列表中的包不会接收此广播
  • 额外数据EXTRA_CHANGED_UID_LIST包含可用性发生变化的包的uid列表。
  • 比如,应用安装在外置卡上,把卡拔掉再插上。
public static final String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE =
    "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";