diff options
| -rw-r--r-- | core/api/current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/content/pm/ModuleInfo.java | 39 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/content/pm/ModuleInfoTest.java | 99 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/ModuleInfoProvider.java | 5 |
4 files changed, 144 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index df073dda254a..7a1008b7d961 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -12368,6 +12368,7 @@ package android.content.pm { public final class ModuleInfo implements android.os.Parcelable { method public int describeContents(); + method @FlaggedApi("android.content.pm.provide_info_of_apk_in_apex") @NonNull public java.util.Collection<java.lang.String> getApkInApexPackageNames(); method @Nullable public CharSequence getName(); method @Nullable public String getPackageName(); method public boolean isHidden(); diff --git a/core/java/android/content/pm/ModuleInfo.java b/core/java/android/content/pm/ModuleInfo.java index a7306a311ad8..a1c874725d4b 100644 --- a/core/java/android/content/pm/ModuleInfo.java +++ b/core/java/android/content/pm/ModuleInfo.java @@ -16,10 +16,15 @@ package android.content.pm; +import android.annotation.FlaggedApi; +import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Objects; /** @@ -46,6 +51,13 @@ public final class ModuleInfo implements Parcelable { /** Whether or not this module is hidden from the user. */ private boolean mHidden; + /** + * The list of the package names of all APK-in-APEX apps in the module, or + * null if there are none. + */ + @Nullable + private List<String> mApkInApexPackageNames; + // TODO: Decide whether we need an additional metadata bundle to support out of band // updates to ModuleInfo. // @@ -61,6 +73,9 @@ public final class ModuleInfo implements Parcelable { mPackageName = orig.mPackageName; mHidden = orig.mHidden; mApexModuleName = orig.mApexModuleName; + if (orig.mApkInApexPackageNames != null) { + mApkInApexPackageNames = List.copyOf(orig.mApkInApexPackageNames); + } } /** @hide Sets the public name of this module. */ @@ -107,6 +122,25 @@ public final class ModuleInfo implements Parcelable { return mApexModuleName; } + /** @hide Sets the list of the package name of APK-in-APEX apps in this module. */ + public ModuleInfo setApkInApexPackageNames(@NonNull Collection<String> apkInApexPackageNames) { + Objects.requireNonNull(apkInApexPackageNames); + mApkInApexPackageNames = List.copyOf(apkInApexPackageNames); + return this; + } + + /** + * Gets the list of the package name of all APK-in-APEX apps in the module. + */ + @NonNull + @FlaggedApi(android.content.pm.Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX) + public Collection<String> getApkInApexPackageNames() { + if (mApkInApexPackageNames == null) { + return Collections.emptyList(); + } + return mApkInApexPackageNames; + } + /** Returns a string representation of this object. */ public String toString() { return "ModuleInfo{" @@ -125,6 +159,7 @@ public final class ModuleInfo implements Parcelable { hashCode = 31 * hashCode + Objects.hashCode(mName); hashCode = 31 * hashCode + Objects.hashCode(mPackageName); hashCode = 31 * hashCode + Objects.hashCode(mApexModuleName); + hashCode = 31 * hashCode + Objects.hashCode(mApkInApexPackageNames); hashCode = 31 * hashCode + Boolean.hashCode(mHidden); return hashCode; } @@ -138,6 +173,7 @@ public final class ModuleInfo implements Parcelable { return Objects.equals(mName, other.mName) && Objects.equals(mPackageName, other.mPackageName) && Objects.equals(mApexModuleName, other.mApexModuleName) + && Objects.equals(mApkInApexPackageNames, other.mApkInApexPackageNames) && mHidden == other.mHidden; } @@ -147,6 +183,8 @@ public final class ModuleInfo implements Parcelable { dest.writeString(mPackageName); dest.writeBoolean(mHidden); dest.writeString(mApexModuleName); + // Parcel#writeStringList handles null case, we can use it directly + dest.writeStringList(mApkInApexPackageNames); } private ModuleInfo(Parcel source) { @@ -154,6 +192,7 @@ public final class ModuleInfo implements Parcelable { mPackageName = source.readString(); mHidden = source.readBoolean(); mApexModuleName = source.readString(); + mApkInApexPackageNames = source.createStringArrayList(); } public static final @android.annotation.NonNull Parcelable.Creator<ModuleInfo> CREATOR = diff --git a/core/tests/coretests/src/android/content/pm/ModuleInfoTest.java b/core/tests/coretests/src/android/content/pm/ModuleInfoTest.java new file mode 100644 index 000000000000..4366e02cdf23 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/ModuleInfoTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.Parcel; +import android.platform.test.annotations.AppModeFull; +import android.text.TextUtils; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.List; + +@RunWith(AndroidJUnit4.class) +@AppModeFull +public class ModuleInfoTest { + + private static final String APEX_MODULE_NAME = "apexModuleName"; + private static final String APK_IN_APEX_PACKAGE_NAME = "apkInApexPackageName"; + private static final String MODULE_PACKAGE_NAME = "modulePackageName"; + private static final String MODULE_NAME = "moduleName"; + + @Test + public void testSimple() { + ModuleInfo info = new ModuleInfo(); + assertThat(info.toString()).isNotNull(); + } + + @Test + public void testDefaultCopy() { + ModuleInfo oldInfo = new ModuleInfo(); + ModuleInfo newInfo = new ModuleInfo(oldInfo); + assertThat(newInfo).isEqualTo(oldInfo); + } + + @Test + public void testCopy() { + boolean isHidden = false; + ModuleInfo info = new ModuleInfo(); + info.setHidden(isHidden); + info.setApexModuleName(APEX_MODULE_NAME); + info.setPackageName(MODULE_PACKAGE_NAME); + info.setName(MODULE_NAME); + info.setApkInApexPackageNames(List.of(APK_IN_APEX_PACKAGE_NAME)); + + ModuleInfo newInfo = new ModuleInfo(info); + assertThat(newInfo).isEqualTo(info); + } + + @Test + public void testGetApkInApexPackageNamesReturnEmptyListInDefault() { + ModuleInfo info = new ModuleInfo(); + assertThat(info.getApkInApexPackageNames()).isNotNull(); + assertThat(info.getApkInApexPackageNames()).isEmpty(); + } + + @Test + public void testModuleInfoParcelizeDeparcelize() { + boolean isHidden = false; + ModuleInfo info = new ModuleInfo(); + info.setHidden(isHidden); + info.setApexModuleName(APEX_MODULE_NAME); + info.setPackageName(MODULE_PACKAGE_NAME); + info.setName(MODULE_NAME); + info.setApkInApexPackageNames(List.of(APK_IN_APEX_PACKAGE_NAME)); + + final Parcel p = Parcel.obtain(); + info.writeToParcel(p, 0); + p.setDataPosition(0); + + final ModuleInfo targetInfo = ModuleInfo.CREATOR.createFromParcel(p); + p.recycle(); + + assertThat(info.isHidden()).isEqualTo(targetInfo.isHidden()); + assertThat(info.getApexModuleName()).isEqualTo(targetInfo.getApexModuleName()); + assertThat(info.getPackageName()).isEqualTo(targetInfo.getPackageName()); + assertThat(TextUtils.equals(info.getName(), targetInfo.getName())).isTrue(); + assertThat(info.getApkInApexPackageNames().toArray()).isEqualTo( + targetInfo.getApkInApexPackageNames().toArray()); + } +} diff --git a/services/core/java/com/android/server/pm/ModuleInfoProvider.java b/services/core/java/com/android/server/pm/ModuleInfoProvider.java index 230f5558b37d..6561d462e716 100644 --- a/services/core/java/com/android/server/pm/ModuleInfoProvider.java +++ b/services/core/java/com/android/server/pm/ModuleInfoProvider.java @@ -18,6 +18,7 @@ package com.android.server.pm; import android.annotation.NonNull; import android.content.Context; +import android.content.pm.Flags; import android.content.pm.IPackageManager; import android.content.pm.ModuleInfo; import android.content.pm.PackageInfo; @@ -165,6 +166,10 @@ public class ModuleInfoProvider { mi.setApexModuleName( mApexManager.getApexModuleNameForPackageName(modulePackageName)); + if (Flags.provideInfoOfApkInApex()) { + mi.setApkInApexPackageNames(mApexManager.getApksInApex(modulePackageName)); + } + mModuleInfo.put(modulePackageName, mi); } } catch (XmlPullParserException | IOException e) { |