Merge "Make sure always reuse ApplicationInfo when generating ProviderInfo" into rvc-dev

This commit is contained in:
Makoto Onuki
2020-02-26 08:46:22 +00:00
committed by Android (Google) Code Review
4 changed files with 79 additions and 51 deletions

View File

@@ -57,6 +57,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.server.IntentResolver; import com.android.server.IntentResolver;
import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageInfoUtils.CachedApplicationInfoGenerator;
import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -273,9 +274,7 @@ public class ComponentResolver {
return null; return null;
} }
List<ProviderInfo> providerList = null; List<ProviderInfo> providerList = null;
CachedApplicationInfoGenerator appInfoGenerator = null;
// Map from a package name to the corresponding app info.
ArrayMap<String, ApplicationInfo> appInfos = null;
synchronized (mLock) { synchronized (mLock) {
for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) { for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) {
final ParsedProvider p = mProviders.mProviders.valueAt(i); final ParsedProvider p = mProviders.mProviders.valueAt(i);
@@ -304,26 +303,15 @@ public class ComponentResolver {
&& (p.getMetaData() == null || !p.getMetaData().containsKey(metaDataKey))) { && (p.getMetaData() == null || !p.getMetaData().containsKey(metaDataKey))) {
continue; continue;
} }
if (appInfoGenerator == null) {
// Make sure we have AppInfo for this provider. appInfoGenerator = new CachedApplicationInfoGenerator();
final PackageUserState state = ps.readUserState(userId); }
ApplicationInfo appInfo = final PackageUserState state = ps.readUserState(userId);
(appInfos == null) ? null : appInfos.get(pkg.getPackageName()); final ApplicationInfo appInfo =
if (appInfo == null) { appInfoGenerator.generate(pkg, flags, state, userId, ps);
appInfo = PackageInfoUtils.generateApplicationInfo( if (appInfo == null) {
pkg, flags, state, userId, ps); continue;
if (appInfo == null) {
// In this case, we should avoid calling generateApplicationInfo() for
// the same package in subsequent iterations, but appInfo shouldn't be null
// here, so we don't bother.
continue;
}
if (appInfos == null) {
appInfos = new ArrayMap<>(4);
}
appInfos.put(pkg.getPackageName(), appInfo);
} }
// At this point, appInfo != null.
final ProviderInfo info = PackageInfoUtils.generateProviderInfo( final ProviderInfo info = PackageInfoUtils.generateProviderInfo(
pkg, p, flags, state, appInfo, userId, ps); pkg, p, flags, state, appInfo, userId, ps);
@@ -355,14 +343,20 @@ public class ComponentResolver {
if (pkg == null) { if (pkg == null) {
return null; return null;
} }
return PackageInfoUtils.generateProviderInfo(pkg, p, flags, final PackageUserState state = ps.readUserState(userId);
ps.readUserState(userId), userId, ps); ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
pkg, flags, state, userId, ps);
if (appInfo == null) {
return null;
}
return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, appInfo, userId, ps);
} }
} }
void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo, boolean safeMode, void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo, boolean safeMode,
int userId) { int userId) {
synchronized (mLock) { synchronized (mLock) {
CachedApplicationInfoGenerator appInfoGenerator = null;
for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) { for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) {
final ParsedProvider p = mProvidersByAuthority.valueAt(i); final ParsedProvider p = mProvidersByAuthority.valueAt(i);
if (!p.isSyncable()) { if (!p.isSyncable()) {
@@ -384,9 +378,18 @@ public class ComponentResolver {
if (safeMode && !pkg.isSystem()) { if (safeMode && !pkg.isSystem()) {
continue; continue;
} }
final ProviderInfo info = if (appInfoGenerator == null) {
PackageInfoUtils.generateProviderInfo(pkg, p, 0, appInfoGenerator = new CachedApplicationInfoGenerator();
ps.readUserState(userId), userId, ps); }
final PackageUserState state = ps.readUserState(userId);
final ApplicationInfo appInfo =
appInfoGenerator.generate(pkg, 0, state, userId, ps);
if (appInfo == null) {
continue;
}
final ProviderInfo info = PackageInfoUtils.generateProviderInfo(
pkg, p, 0, state, appInfo, userId, ps);
if (info == null) { if (info == null) {
continue; continue;
} }
@@ -1731,8 +1734,13 @@ public class ComponentResolver {
if (userState.instantApp && ps.isUpdateAvailable()) { if (userState.instantApp && ps.isUpdateAvailable()) {
return null; return null;
} }
final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
pkg, mFlags, userState, userId, ps);
if (appInfo == null) {
return null;
}
ProviderInfo pi = PackageInfoUtils.generateProviderInfo(pkg, provider, mFlags, ProviderInfo pi = PackageInfoUtils.generateProviderInfo(pkg, provider, mFlags,
userState, userId, ps); userState, appInfo, userId, ps);
if (pi == null) { if (pi == null) {
return null; return null;
} }

View File

@@ -5459,7 +5459,13 @@ public class PackageManagerService extends IPackageManager.Stub
return null; return null;
} }
PackageUserState state = ps.readUserState(userId); PackageUserState state = ps.readUserState(userId);
return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, userId, ps); final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
pkg, flags, state, userId, ps);
if (appInfo == null) {
return null;
}
return PackageInfoUtils.generateProviderInfo(
pkg, p, flags, state, appInfo, userId, ps);
} }
} }
return null; return null;

View File

@@ -48,7 +48,7 @@ import android.content.pm.parsing.component.ParsedService;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Pair; import android.util.Slog;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.server.pm.PackageSetting; import com.android.server.pm.PackageSetting;
@@ -61,6 +61,7 @@ import libcore.util.EmptyArray;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set; import java.util.Set;
@@ -72,6 +73,7 @@ import java.util.Set;
* @hide * @hide
**/ **/
public class PackageInfoUtils { public class PackageInfoUtils {
private static final String TAG = PackageParser2.TAG;
/** /**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
@@ -310,37 +312,24 @@ public class PackageInfoUtils {
return info; return info;
} }
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*
* @deprecated use {@link #generateProviderInfo(
* AndroidPackage, ParsedProvider, int, PackageUserState, ApplicationInfo, int, PackageSetting)}
* instead and pass {@link ApplicationInfo} explicitly to avoid generating duplicate instances
* of it.
*/
@Nullable
@Deprecated
public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p,
@PackageManager.ComponentInfoFlags int flags, PackageUserState state, int userId,
@Nullable PackageSetting pkgSetting) {
return generateProviderInfo(pkg, p, flags, state, null, userId, pkgSetting);
}
/** /**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*/ */
@Nullable @Nullable
public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p, public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p,
@PackageManager.ComponentInfoFlags int flags, PackageUserState state, @PackageManager.ComponentInfoFlags int flags, PackageUserState state,
@Nullable ApplicationInfo applicationInfo, int userId, @NonNull ApplicationInfo applicationInfo, int userId,
@Nullable PackageSetting pkgSetting) { @Nullable PackageSetting pkgSetting) {
if (p == null) return null; if (p == null) return null;
if (applicationInfo == null || !pkg.getPackageName().equals(applicationInfo.packageName)) {
Slog.wtf(TAG, "AppInfo's package name is different. Expected=" + pkg.getPackageName()
+ " actual=" + (applicationInfo == null ? "(null AppInfo)"
: applicationInfo.packageName));
applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting);
}
if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) {
return null; return null;
} }
if (applicationInfo == null) {
applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting);
}
ProviderInfo info = PackageInfoWithoutStateUtils.generateProviderInfo(pkg, p, flags, state, ProviderInfo info = PackageInfoWithoutStateUtils.generateProviderInfo(pkg, p, flags, state,
applicationInfo, userId); applicationInfo, userId);
if (info == null) { if (info == null) {
@@ -486,4 +475,29 @@ public class PackageInfoUtils {
| flag(pkg.isSignedWithPlatformKey(), ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY); | flag(pkg.isSignedWithPlatformKey(), ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY);
// @formatter:on // @formatter:on
} }
/**
* Wraps {@link PackageInfoUtils#generateApplicationInfo} with a cache.
*/
public static class CachedApplicationInfoGenerator {
// Map from a package name to the corresponding app info.
private ArrayMap<String, ApplicationInfo> mCache = new ArrayMap<>();
/**
* {@link PackageInfoUtils#generateApplicationInfo} with a cache.
*/
@Nullable
public ApplicationInfo generate(AndroidPackage pkg,
@PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId,
@Nullable PackageSetting pkgSetting) {
ApplicationInfo appInfo = mCache.get(pkg.getPackageName());
if (appInfo != null) {
return appInfo;
}
appInfo = PackageInfoUtils.generateApplicationInfo(
pkg, flags, state, userId, pkgSetting);
mCache.put(pkg.getPackageName(), appInfo);
return appInfo;
}
}
} }

View File

@@ -42,7 +42,7 @@ import java.io.File;
*/ */
public class PackageParser2 { public class PackageParser2 {
private static final String TAG = "PackageParser2"; static final String TAG = "PackageParser2";
private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE; private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE;
private static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100; private static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100;