From f93af7ef7ebe9d139a34e615b97393a41ebabb56 Mon Sep 17 00:00:00 2001 From: Winson Date: Fri, 18 Jun 2021 11:17:50 -0700 Subject: [PATCH] Fix parsing code parcelling errors Address problems reading/writing: - ParsedComponent mProperties - ParsingPackageImpl mKeySetMapping - ParsingPackageImpl mQueriesIntent Bug: 187043377 Test: atest com.android.server.pm.test.parsing.parcelling Change-Id: I5b33315f8248d5fcbdef2cc04ecf77cc18dbd7b6 --- .../pm/parsing/ParsingPackageImpl.java | 6 +- .../pm/parsing/ParsingPackageUtils.java | 63 +++++++++++++++++++ .../pm/parsing/component/ParsedComponent.java | 2 +- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index 4c44ba1fc9ef2..5a7f21040d0a0 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -1164,7 +1164,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeTypedList(this.usesPermissions); sForInternedStringList.parcel(this.implicitPermissions, dest, flags); sForStringSet.parcel(this.upgradeKeySets, dest, flags); - dest.writeMap(this.keySetMapping); + ParsingPackageUtils.writeKeySetMapping(dest, this.keySetMapping); sForInternedStringList.parcel(this.protectedBroadcasts, dest, flags); dest.writeTypedList(this.activities); dest.writeTypedList(this.receivers); @@ -1180,7 +1180,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { sForInternedString.parcel(this.volumeUuid, dest, flags); dest.writeParcelable(this.signingDetails, flags); dest.writeString(this.mPath); - dest.writeParcelableList(this.queriesIntents, flags); + dest.writeTypedList(this.queriesIntents, flags); sForInternedStringList.parcel(this.queriesPackages, dest, flags); sForInternedStringSet.parcel(this.queriesProviders, dest, flags); dest.writeString(this.appComponentFactory); @@ -1287,7 +1287,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.usesPermissions = in.createTypedArrayList(ParsedUsesPermission.CREATOR); this.implicitPermissions = sForInternedStringList.unparcel(in); this.upgradeKeySets = sForStringSet.unparcel(in); - this.keySetMapping = in.readHashMap(boot); + this.keySetMapping = ParsingPackageUtils.readKeySetMapping(in); this.protectedBroadcasts = sForInternedStringList.unparcel(in); this.activities = in.createTypedArrayList(ParsedActivity.CREATOR); diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 6fd533355aad7..dce242c9d87c5 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -87,6 +87,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.FileUtils; +import android.os.Parcel; import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; @@ -3159,6 +3160,68 @@ public class ParsingPackageUtils { return sa.getNonResourceString(index); } + /** + * Writes the keyset mapping to the provided package. {@code null} mappings are permitted. + */ + public static void writeKeySetMapping(@NonNull Parcel dest, + @NonNull Map> keySetMapping) { + if (keySetMapping == null) { + dest.writeInt(-1); + return; + } + + final int N = keySetMapping.size(); + dest.writeInt(N); + + for (String key : keySetMapping.keySet()) { + dest.writeString(key); + ArraySet keys = keySetMapping.get(key); + if (keys == null) { + dest.writeInt(-1); + continue; + } + + final int M = keys.size(); + dest.writeInt(M); + for (int j = 0; j < M; j++) { + dest.writeSerializable(keys.valueAt(j)); + } + } + } + + /** + * Reads a keyset mapping from the given parcel at the given data position. May return + * {@code null} if the serialized mapping was {@code null}. + */ + @NonNull + public static ArrayMap> readKeySetMapping(@NonNull Parcel in) { + final int N = in.readInt(); + if (N == -1) { + return null; + } + + ArrayMap> keySetMapping = new ArrayMap<>(); + for (int i = 0; i < N; ++i) { + String key = in.readString(); + final int M = in.readInt(); + if (M == -1) { + keySetMapping.put(key, null); + continue; + } + + ArraySet keys = new ArraySet<>(M); + for (int j = 0; j < M; ++j) { + PublicKey pk = (PublicKey) in.readSerializable(); + keys.add(pk); + } + + keySetMapping.put(key, keys); + } + + return keySetMapping; + } + + /** * Callback interface for retrieving information that may be needed while parsing * a package. diff --git a/core/java/android/content/pm/parsing/component/ParsedComponent.java b/core/java/android/content/pm/parsing/component/ParsedComponent.java index 4aed77ae641b7..9d830ec7a227d 100644 --- a/core/java/android/content/pm/parsing/component/ParsedComponent.java +++ b/core/java/android/content/pm/parsing/component/ParsedComponent.java @@ -172,7 +172,7 @@ public abstract class ParsedComponent implements Parcelable { this.packageName = sForInternedString.unparcel(in); this.intents = sForIntentInfos.unparcel(in); this.metaData = in.readBundle(boot); - this.mProperties = in.createTypedArrayMap(Property.CREATOR); + this.mProperties = in.readHashMap(boot); } @NonNull