Merge "Make sure always reuse ApplicationInfo when generating ProviderInfo" into rvc-dev
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user