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

Commit 8ebc0431 authored by Oli Lan's avatar Oli Lan
Browse files

Allow ModuleInfo to be retrieved using apex name.

This adds the apex name (a.k.a. apex module name) to ModuleInfo, and adds a
flag to allow the apex name to be used when calling getModuleInfo.

The existing ModuleInfoFlags was only used for getInstalledModules, so it
has been renamed accordingly.

See go/apex-package-info-discovery

Bug: 141149569
Test: added apex name checks to ModuleInfoProviderTest
Change-Id: I5bcfaa0ef227f3b4eca963e57de4d25c08676c9c
parent aca9fccf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2266,6 +2266,7 @@ package android.content.pm {
    field public static final int MATCH_ANY_USER = 4194304; // 0x400000
    field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
    field public static final int MATCH_INSTANT = 8388608; // 0x800000
    field public static final int MODULE_APEX_NAME = 1; // 0x1
    field public static final int RESTRICTION_HIDE_FROM_SUGGESTIONS = 1; // 0x1
    field public static final int RESTRICTION_HIDE_NOTIFICATIONS = 2; // 0x2
    field public static final int RESTRICTION_NONE = 0; // 0x0
+22 −0
Original line number Diff line number Diff line
@@ -37,6 +37,12 @@ public final class ModuleInfo implements Parcelable {
    /** The package name of this module. */
    private String mPackageName;

    /**
     * The name of the APEX this module is distributed as, or null if it is not distributed via
     * APEX.
     */
    @Nullable private String mApexModuleName;

    /** Whether or not this module is hidden from the user. */
    private boolean mHidden;

@@ -54,6 +60,7 @@ public final class ModuleInfo implements Parcelable {
        mName = orig.mName;
        mPackageName = orig.mPackageName;
        mHidden = orig.mHidden;
        mApexModuleName = orig.mApexModuleName;
    }

    /** @hide Sets the public name of this module. */
@@ -89,6 +96,17 @@ public final class ModuleInfo implements Parcelable {
        return mHidden;
    }

    /** @hide Sets the apex module name. */
    public ModuleInfo setApexModuleName(@Nullable String apexModuleName) {
        mApexModuleName = apexModuleName;
        return this;
    }

    /** @hide Gets the apex module name. */
    public @Nullable String getApexModuleName() {
        return mApexModuleName;
    }

    /** Returns a string representation of this object. */
    public String toString() {
        return "ModuleInfo{"
@@ -106,6 +124,7 @@ public final class ModuleInfo implements Parcelable {
        int hashCode = 0;
        hashCode = 31 * hashCode + Objects.hashCode(mName);
        hashCode = 31 * hashCode + Objects.hashCode(mPackageName);
        hashCode = 31 * hashCode + Objects.hashCode(mApexModuleName);
        hashCode = 31 * hashCode + Boolean.hashCode(mHidden);
        return hashCode;
    }
@@ -118,6 +137,7 @@ public final class ModuleInfo implements Parcelable {
        final ModuleInfo other = (ModuleInfo) obj;
        return Objects.equals(mName, other.mName)
                && Objects.equals(mPackageName, other.mPackageName)
                && Objects.equals(mApexModuleName, other.mApexModuleName)
                && mHidden == other.mHidden;
    }

@@ -126,12 +146,14 @@ public final class ModuleInfo implements Parcelable {
        dest.writeCharSequence(mName);
        dest.writeString(mPackageName);
        dest.writeBoolean(mHidden);
        dest.writeString(mApexModuleName);
    }

    private ModuleInfo(Parcel source) {
        mName = source.readCharSequence();
        mPackageName = source.readString();
        mHidden = source.readBoolean();
        mApexModuleName = source.readString();
    }

    public static final @android.annotation.NonNull Parcelable.Creator<ModuleInfo> CREATOR =
+18 −2
Original line number Diff line number Diff line
@@ -229,7 +229,7 @@ public abstract class PackageManager {
            MATCH_ALL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ModuleInfoFlags {}
    public @interface InstalledModulesFlags {}

    /** @hide */
    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
@@ -580,6 +580,22 @@ public abstract class PackageManager {
     */
    public static final int ONLY_IF_NO_MATCH_FOUND = 0x00000004;

    /** @hide */
    @IntDef(flag = true, prefix = { "MODULE_" }, value = {
            MODULE_APEX_NAME,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ModuleInfoFlags {}

    /**
     * Flag for {@link #getModuleInfo}: allow ModuleInfo to be retrieved using the apex module
     * name, rather than the package name.
     *
     * @hide
     */
    @SystemApi
    public static final int MODULE_APEX_NAME = 0x00000001;

    /** @hide */
    @IntDef(prefix = { "PERMISSION_" }, value = {
            PERMISSION_GRANTED,
@@ -3928,7 +3944,7 @@ public abstract class PackageManager {
     *         there are no installed modules, an empty list is returned.
     */
    @NonNull
    public List<ModuleInfo> getInstalledModules(@ModuleInfoFlags int flags) {
    public List<ModuleInfo> getInstalledModules(@InstalledModulesFlags int flags) {
        throw new UnsupportedOperationException(
                "getInstalledModules not implemented in subclass");
    }
+23 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ import java.util.stream.Collectors;
 * ApexManager class handles communications with the apex service to perform operation and queries,
 * as well as providing caching to avoid unnecessary calls to the service.
 */
abstract class ApexManager {
public abstract class ApexManager {

    private static final String TAG = "ApexManager";

@@ -264,6 +264,13 @@ abstract class ApexManager {
     */
    abstract List<String> getApksInApex(String apexPackageName);

    /**
     * Returns the apex module name for the given package name, if the package is an APEX. Otherwise
     * returns {@code null}.
     */
    @Nullable
    public abstract String getApexModuleNameForPackageName(String apexPackageName);

    /**
     * Dumps various state information to the provided {@link PrintWriter} object.
     *
@@ -646,6 +653,15 @@ abstract class ApexManager {
            }
        }

        @Override
        @Nullable
        public String getApexModuleNameForPackageName(String apexPackageName) {
            populatePackageNameToApexModuleNameIfNeeded();
            synchronized (mLock) {
                return mPackageNameToApexModuleName.get(apexPackageName);
            }
        }

        /**
         * Dump information about the packages contained in a particular cache
         * @param packagesCache the cache to print information about.
@@ -842,6 +858,12 @@ abstract class ApexManager {
            return Collections.emptyList();
        }

        @Override
        @Nullable
        public String getApexModuleNameForPackageName(String apexPackageName) {
            return null;
        }

        @Override
        void dump(PrintWriter pw, String packageName) {
            // No-op
+18 −6
Original line number Diff line number Diff line
@@ -57,9 +57,9 @@ public class ModuleInfoProvider {
     */
    private static final String MODULE_METADATA_KEY = "android.content.pm.MODULE_METADATA";


    private final Context mContext;
    private final IPackageManager mPackageManager;
    private final ApexManager mApexManager;
    private final Map<String, ModuleInfo> mModuleInfo;

    // TODO: Move this to an earlier boot phase if anybody requires it then.
@@ -69,13 +69,16 @@ public class ModuleInfoProvider {
    ModuleInfoProvider(Context context, IPackageManager packageManager) {
        mContext = context;
        mPackageManager = packageManager;
        mApexManager = ApexManager.getInstance();
        mModuleInfo = new ArrayMap<>();
    }

    @VisibleForTesting
    public ModuleInfoProvider(XmlResourceParser metadata, Resources resources) {
    public ModuleInfoProvider(
            XmlResourceParser metadata, Resources resources, ApexManager apexManager) {
        mContext = null;
        mPackageManager = null;
        mApexManager = apexManager;
        mModuleInfo = new ArrayMap<>();
        loadModuleMetadata(metadata, resources);
    }
@@ -150,6 +153,8 @@ public class ModuleInfoProvider {
                mi.setHidden(isHidden);
                mi.setPackageName(modulePackageName);
                mi.setName(moduleName);
                mi.setApexModuleName(
                        mApexManager.getApexModuleNameForPackageName(modulePackageName));

                mModuleInfo.put(modulePackageName, mi);
            }
@@ -167,7 +172,7 @@ public class ModuleInfoProvider {
     *
     * @param flags Use {@link PackageManager#MATCH_ALL} flag to get all modules.
     */
    List<ModuleInfo> getInstalledModules(@PackageManager.ModuleInfoFlags int flags) {
    List<ModuleInfo> getInstalledModules(@PackageManager.InstalledModulesFlags int flags) {
        if (!mMetadataLoaded) {
            throw new IllegalStateException("Call to getInstalledModules before metadata loaded");
        }
@@ -195,12 +200,19 @@ public class ModuleInfoProvider {
        return installedModules;
    }

    ModuleInfo getModuleInfo(String packageName, int flags) {
    ModuleInfo getModuleInfo(String name, @PackageManager.ModuleInfoFlags int flags) {
        if (!mMetadataLoaded) {
            throw new IllegalStateException("Call to getModuleInfo before metadata loaded");
        }

        return mModuleInfo.get(packageName);
        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);
    }

    String getPackageName() {
Loading