Loading core/java/android/content/pm/PackageParser.java +17 −2 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageParserCacheHelper.ReadHelper; import android.content.pm.PackageParserCacheHelper.WriteHelper; import android.content.pm.split.DefaultSplitAssetLoader; import android.content.pm.split.SplitAssetDependencyLoader; import android.content.pm.split.SplitAssetLoader; Loading Loading @@ -1024,11 +1026,17 @@ public class PackageParser { @VisibleForTesting protected Package fromCacheEntry(byte[] bytes) throws IOException { Parcel p = Parcel.obtain(); final ReadHelper helper = new ReadHelper(); final Parcel p = Parcel.obtain(); p.setReadWriteHelper(helper); p.unmarshall(bytes, 0, bytes.length); p.setDataPosition(0); helper.start(p); PackageParser.Package pkg = new PackageParser.Package(p); p.recycle(); return pkg; Loading @@ -1036,8 +1044,15 @@ public class PackageParser { @VisibleForTesting protected byte[] toCacheEntry(Package pkg) throws IOException { Parcel p = Parcel.obtain(); final WriteHelper helper = new WriteHelper(); final Parcel p = Parcel.obtain(); p.setReadWriteHelper(helper); pkg.writeToParcel(p, 0 /* flags */); helper.finish(p); byte[] serialized = p.marshall(); p.recycle(); Loading core/java/android/content/pm/PackageParserCacheHelper.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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 android.os.Parcel; import java.util.ArrayList; import java.util.HashMap; /** * Helper classes to read from and write to Parcel with pooled strings. * * @hide */ public class PackageParserCacheHelper { private PackageParserCacheHelper() { } /** * Parcel read helper with a string pool. */ public static class ReadHelper extends Parcel.ReadWriteHelper { private final ArrayList<String> mStrings = new ArrayList<>(); public ReadHelper() { } /** * Prepare a parcel. */ public void start(Parcel p) { mStrings.clear(); final int poolPosition = p.readInt(); final int startPosition = p.dataPosition(); // The pool is at the end of the parcel. p.setDataPosition(poolPosition); p.readStringList(mStrings); // Then move back. p.setDataPosition(startPosition); } /** * Read an string index from a parcel, and returns the corresponding string from the pool. */ @Override public String readString(Parcel p) { return mStrings.get(p.readInt()); } } /** * Parcel write helper with a string pool. */ public static class WriteHelper extends Parcel.ReadWriteHelper { private final ArrayList<String> mStrings = new ArrayList<>(); private final HashMap<String, Integer> mIndexes = new HashMap<>(); public WriteHelper() { } /** * Instead of writing a string directly to a parcel, this method adds it to the pool, * and write the index in the pool to the parcel. */ @Override public void writeString(Parcel p, String s) { final Integer cur = mIndexes.get(s); if (cur != null) { // String already in the pool. Just write the index. p.writeInt(cur); // Already in the pool. } else { // Note in the pool. Add to the pool, and write the index. final int index = mStrings.size(); mIndexes.put(s, index); mStrings.add(s); p.writeInt(index); } } /** * Closes a parcel by appending the string pool at the end and updating the pool offset, * which it assumes is at the first byte. */ public void finish(Parcel p) { final int poolPosition = p.readInt(); p.writeStringList(mStrings); p.setDataPosition(0); p.writeInt(poolPosition); // Move back to the end. p.setDataPosition(p.dataSize()); } } } core/java/android/os/Parcel.java +64 −2 Original line number Diff line number Diff line Loading @@ -291,7 +291,7 @@ public final class Parcel { private static native void nativeWriteFloat(long nativePtr, float val); @FastNative private static native void nativeWriteDouble(long nativePtr, double val); private static native void nativeWriteString(long nativePtr, String val); static native void nativeWriteString(long nativePtr, String val); private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val); Loading @@ -306,7 +306,7 @@ public final class Parcel { private static native float nativeReadFloat(long nativePtr); @CriticalNative private static native double nativeReadDouble(long nativePtr); private static native String nativeReadString(long nativePtr); static native String nativeReadString(long nativePtr); private static native IBinder nativeReadStrongBinder(long nativePtr); private static native FileDescriptor nativeReadFileDescriptor(long nativePtr); Loading Loading @@ -338,6 +338,33 @@ public final class Parcel { } }; /** * @hide */ public static class ReadWriteHelper { public static final ReadWriteHelper DEFAULT = new ReadWriteHelper(); /** * Called when writing a string to a parcel. Subclasses wanting to write a string * must use {@link #writeStringNoHelper(String)} to avoid * infinity recursive calls. */ public void writeString(Parcel p, String s) { nativeWriteString(p.mNativePtr, s); } /** * Called when reading a string to a parcel. Subclasses wanting to read a string * must use {@link #readStringNoHelper()} to avoid * infinity recursive calls. */ public String readString(Parcel p) { return nativeReadString(p.mNativePtr); } } private ReadWriteHelper mReadWriteHelper = ReadWriteHelper.DEFAULT; /** * Retrieve a new Parcel object from the pool. */ Loading @@ -352,6 +379,7 @@ public final class Parcel { if (DEBUG_RECYCLE) { p.mStack = new RuntimeException(); } p.mReadWriteHelper = ReadWriteHelper.DEFAULT; return p; } } Loading Loading @@ -385,6 +413,16 @@ public final class Parcel { } } /** * Set a {@link ReadWriteHelper}, which can be used to avoid having duplicate strings, for * example. * * @hide */ public void setReadWriteHelper(ReadWriteHelper helper) { mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT; } /** @hide */ public static native long getGlobalAllocSize(); Loading Loading @@ -625,6 +663,17 @@ public final class Parcel { * growing dataCapacity() if needed. */ public final void writeString(String val) { mReadWriteHelper.writeString(this, val); } /** * Write a string without going though a {@link ReadWriteHelper}. Subclasses of * {@link ReadWriteHelper} must use this method instead of {@link #writeString} to avoid * infinity recursive calls. * * @hide */ public void writeStringNoHelper(String val) { nativeWriteString(mNativePtr, val); } Loading Loading @@ -1996,6 +2045,17 @@ public final class Parcel { * Read a string value from the parcel at the current dataPosition(). */ public final String readString() { return mReadWriteHelper.readString(this); } /** * Read a string without going though a {@link ReadWriteHelper}. Subclasses of * {@link ReadWriteHelper} must use this method instead of {@link #readString} to avoid * infinity recursive calls. * * @hide */ public String readStringNoHelper() { return nativeReadString(mNativePtr); } Loading Loading @@ -2996,6 +3056,7 @@ public final class Parcel { if (mOwnsNativeParcelObject) { updateNativeSize(nativeFreeBuffer(mNativePtr)); } mReadWriteHelper = ReadWriteHelper.DEFAULT; } private void destroy() { Loading @@ -3006,6 +3067,7 @@ public final class Parcel { } mNativePtr = 0; } mReadWriteHelper = null; } @Override Loading Loading
core/java/android/content/pm/PackageParser.java +17 −2 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageParserCacheHelper.ReadHelper; import android.content.pm.PackageParserCacheHelper.WriteHelper; import android.content.pm.split.DefaultSplitAssetLoader; import android.content.pm.split.SplitAssetDependencyLoader; import android.content.pm.split.SplitAssetLoader; Loading Loading @@ -1024,11 +1026,17 @@ public class PackageParser { @VisibleForTesting protected Package fromCacheEntry(byte[] bytes) throws IOException { Parcel p = Parcel.obtain(); final ReadHelper helper = new ReadHelper(); final Parcel p = Parcel.obtain(); p.setReadWriteHelper(helper); p.unmarshall(bytes, 0, bytes.length); p.setDataPosition(0); helper.start(p); PackageParser.Package pkg = new PackageParser.Package(p); p.recycle(); return pkg; Loading @@ -1036,8 +1044,15 @@ public class PackageParser { @VisibleForTesting protected byte[] toCacheEntry(Package pkg) throws IOException { Parcel p = Parcel.obtain(); final WriteHelper helper = new WriteHelper(); final Parcel p = Parcel.obtain(); p.setReadWriteHelper(helper); pkg.writeToParcel(p, 0 /* flags */); helper.finish(p); byte[] serialized = p.marshall(); p.recycle(); Loading
core/java/android/content/pm/PackageParserCacheHelper.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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 android.os.Parcel; import java.util.ArrayList; import java.util.HashMap; /** * Helper classes to read from and write to Parcel with pooled strings. * * @hide */ public class PackageParserCacheHelper { private PackageParserCacheHelper() { } /** * Parcel read helper with a string pool. */ public static class ReadHelper extends Parcel.ReadWriteHelper { private final ArrayList<String> mStrings = new ArrayList<>(); public ReadHelper() { } /** * Prepare a parcel. */ public void start(Parcel p) { mStrings.clear(); final int poolPosition = p.readInt(); final int startPosition = p.dataPosition(); // The pool is at the end of the parcel. p.setDataPosition(poolPosition); p.readStringList(mStrings); // Then move back. p.setDataPosition(startPosition); } /** * Read an string index from a parcel, and returns the corresponding string from the pool. */ @Override public String readString(Parcel p) { return mStrings.get(p.readInt()); } } /** * Parcel write helper with a string pool. */ public static class WriteHelper extends Parcel.ReadWriteHelper { private final ArrayList<String> mStrings = new ArrayList<>(); private final HashMap<String, Integer> mIndexes = new HashMap<>(); public WriteHelper() { } /** * Instead of writing a string directly to a parcel, this method adds it to the pool, * and write the index in the pool to the parcel. */ @Override public void writeString(Parcel p, String s) { final Integer cur = mIndexes.get(s); if (cur != null) { // String already in the pool. Just write the index. p.writeInt(cur); // Already in the pool. } else { // Note in the pool. Add to the pool, and write the index. final int index = mStrings.size(); mIndexes.put(s, index); mStrings.add(s); p.writeInt(index); } } /** * Closes a parcel by appending the string pool at the end and updating the pool offset, * which it assumes is at the first byte. */ public void finish(Parcel p) { final int poolPosition = p.readInt(); p.writeStringList(mStrings); p.setDataPosition(0); p.writeInt(poolPosition); // Move back to the end. p.setDataPosition(p.dataSize()); } } }
core/java/android/os/Parcel.java +64 −2 Original line number Diff line number Diff line Loading @@ -291,7 +291,7 @@ public final class Parcel { private static native void nativeWriteFloat(long nativePtr, float val); @FastNative private static native void nativeWriteDouble(long nativePtr, double val); private static native void nativeWriteString(long nativePtr, String val); static native void nativeWriteString(long nativePtr, String val); private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val); Loading @@ -306,7 +306,7 @@ public final class Parcel { private static native float nativeReadFloat(long nativePtr); @CriticalNative private static native double nativeReadDouble(long nativePtr); private static native String nativeReadString(long nativePtr); static native String nativeReadString(long nativePtr); private static native IBinder nativeReadStrongBinder(long nativePtr); private static native FileDescriptor nativeReadFileDescriptor(long nativePtr); Loading Loading @@ -338,6 +338,33 @@ public final class Parcel { } }; /** * @hide */ public static class ReadWriteHelper { public static final ReadWriteHelper DEFAULT = new ReadWriteHelper(); /** * Called when writing a string to a parcel. Subclasses wanting to write a string * must use {@link #writeStringNoHelper(String)} to avoid * infinity recursive calls. */ public void writeString(Parcel p, String s) { nativeWriteString(p.mNativePtr, s); } /** * Called when reading a string to a parcel. Subclasses wanting to read a string * must use {@link #readStringNoHelper()} to avoid * infinity recursive calls. */ public String readString(Parcel p) { return nativeReadString(p.mNativePtr); } } private ReadWriteHelper mReadWriteHelper = ReadWriteHelper.DEFAULT; /** * Retrieve a new Parcel object from the pool. */ Loading @@ -352,6 +379,7 @@ public final class Parcel { if (DEBUG_RECYCLE) { p.mStack = new RuntimeException(); } p.mReadWriteHelper = ReadWriteHelper.DEFAULT; return p; } } Loading Loading @@ -385,6 +413,16 @@ public final class Parcel { } } /** * Set a {@link ReadWriteHelper}, which can be used to avoid having duplicate strings, for * example. * * @hide */ public void setReadWriteHelper(ReadWriteHelper helper) { mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT; } /** @hide */ public static native long getGlobalAllocSize(); Loading Loading @@ -625,6 +663,17 @@ public final class Parcel { * growing dataCapacity() if needed. */ public final void writeString(String val) { mReadWriteHelper.writeString(this, val); } /** * Write a string without going though a {@link ReadWriteHelper}. Subclasses of * {@link ReadWriteHelper} must use this method instead of {@link #writeString} to avoid * infinity recursive calls. * * @hide */ public void writeStringNoHelper(String val) { nativeWriteString(mNativePtr, val); } Loading Loading @@ -1996,6 +2045,17 @@ public final class Parcel { * Read a string value from the parcel at the current dataPosition(). */ public final String readString() { return mReadWriteHelper.readString(this); } /** * Read a string without going though a {@link ReadWriteHelper}. Subclasses of * {@link ReadWriteHelper} must use this method instead of {@link #readString} to avoid * infinity recursive calls. * * @hide */ public String readStringNoHelper() { return nativeReadString(mNativePtr); } Loading Loading @@ -2996,6 +3056,7 @@ public final class Parcel { if (mOwnsNativeParcelObject) { updateNativeSize(nativeFreeBuffer(mNativePtr)); } mReadWriteHelper = ReadWriteHelper.DEFAULT; } private void destroy() { Loading @@ -3006,6 +3067,7 @@ public final class Parcel { } mNativePtr = 0; } mReadWriteHelper = null; } @Override Loading