Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db91e180 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Make sure always reuse ApplicationInfo when generating ProviderInfo

Bug: 148588589
Test: atest CtsContentTestCases (modulo preexisting failures)
Change-Id: If81f3b343fb018ba52127d038d02e62ca516c18f
parent 9577cd78
Loading
Loading
Loading
Loading
+34 −26
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
import com.android.server.IntentResolver;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageInfoUtils.CachedApplicationInfoGenerator;
import com.android.server.pm.parsing.pkg.AndroidPackage;

import java.io.PrintWriter;
@@ -273,9 +274,7 @@ public class ComponentResolver {
            return null;
        }
        List<ProviderInfo> providerList = null;

        // Map from a package name to the corresponding app info.
        ArrayMap<String, ApplicationInfo> appInfos = null;
        CachedApplicationInfoGenerator appInfoGenerator = null;
        synchronized (mLock) {
            for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) {
                final ParsedProvider p = mProviders.mProviders.valueAt(i);
@@ -304,26 +303,15 @@ public class ComponentResolver {
                        && (p.getMetaData() == null || !p.getMetaData().containsKey(metaDataKey))) {
                    continue;
                }

                // Make sure we have AppInfo for this provider.
                if (appInfoGenerator == null) {
                    appInfoGenerator = new CachedApplicationInfoGenerator();
                }
                final PackageUserState state = ps.readUserState(userId);
                ApplicationInfo appInfo =
                        (appInfos == null) ? null : appInfos.get(pkg.getPackageName());
                final ApplicationInfo appInfo =
                        appInfoGenerator.generate(pkg, flags, state, userId, ps);
                if (appInfo == null) {
                    appInfo = PackageInfoUtils.generateApplicationInfo(
                            pkg, flags, state, userId, ps);
                    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(
                        pkg, p, flags, state, appInfo, userId, ps);
@@ -355,14 +343,20 @@ public class ComponentResolver {
            if (pkg == null) {
                return null;
            }
            return PackageInfoUtils.generateProviderInfo(pkg, p, flags,
                    ps.readUserState(userId), userId, ps);
            final PackageUserState state = ps.readUserState(userId);
            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,
            int userId) {
        synchronized (mLock) {
            CachedApplicationInfoGenerator appInfoGenerator = null;
            for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) {
                final ParsedProvider p = mProvidersByAuthority.valueAt(i);
                if (!p.isSyncable()) {
@@ -384,9 +378,18 @@ public class ComponentResolver {
                if (safeMode && !pkg.isSystem()) {
                    continue;
                }
                final ProviderInfo info =
                        PackageInfoUtils.generateProviderInfo(pkg, p, 0,
                                ps.readUserState(userId), userId, ps);
                if (appInfoGenerator == null) {
                    appInfoGenerator = new CachedApplicationInfoGenerator();
                }
                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) {
                    continue;
                }
@@ -1731,8 +1734,13 @@ public class ComponentResolver {
            if (userState.instantApp && ps.isUpdateAvailable()) {
                return null;
            }
            final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
                    pkg, mFlags, userState, userId, ps);
            if (appInfo == null) {
                return null;
            }
            ProviderInfo pi = PackageInfoUtils.generateProviderInfo(pkg, provider, mFlags,
                    userState, userId, ps);
                    userState, appInfo, userId, ps);
            if (pi == null) {
                return null;
            }
+7 −1
Original line number Diff line number Diff line
@@ -5459,7 +5459,13 @@ public class PackageManagerService extends IPackageManager.Stub
                    return null;
                }
                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;
+35 −21
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ import android.content.pm.parsing.component.ParsedService;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;

import com.android.internal.util.ArrayUtils;
import com.android.server.pm.PackageSetting;
@@ -61,6 +61,7 @@ import libcore.util.EmptyArray;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;


@@ -72,6 +73,7 @@ import java.util.Set;
 * @hide
 **/
public class PackageInfoUtils {
    private static final String TAG = PackageParser2.TAG;

    /**
     * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
@@ -310,37 +312,24 @@ public class PackageInfoUtils {
        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.
     */
    @Nullable
    public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p,
            @PackageManager.ComponentInfoFlags int flags, PackageUserState state,
            @Nullable ApplicationInfo applicationInfo, int userId,
            @NonNull ApplicationInfo applicationInfo, int userId,
            @Nullable PackageSetting pkgSetting) {
        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)) {
            return null;
        }
        if (applicationInfo == null) {
            applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting);
        }
        ProviderInfo info = PackageInfoWithoutStateUtils.generateProviderInfo(pkg, p, flags, state,
                applicationInfo, userId);
        if (info == null) {
@@ -486,4 +475,29 @@ public class PackageInfoUtils {
                | flag(pkg.isSignedWithPlatformKey(), ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY);
        // @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;
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ import java.io.File;
 */
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 int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100;