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";