summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/content/pm/ModuleInfo.java39
-rw-r--r--core/tests/coretests/src/android/content/pm/ModuleInfoTest.java99
-rw-r--r--services/core/java/com/android/server/pm/ModuleInfoProvider.java5
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) {