From f7345b6f0b894aa519c09cb6dc35aff9d7cb0f8c Mon Sep 17 00:00:00 2001 From: roger2015 Date: Tue, 11 Mar 2025 20:14:20 +0800 Subject: [PATCH 1/2] add file --- .../src/main/java/dalvik/system/DexFile.java | 811 ++++++++++++++++++ 1 file changed, 811 insertions(+) create mode 100644 aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java diff --git a/aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java b/aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java new file mode 100644 index 000000000..8d73604e0 --- /dev/null +++ b/aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java @@ -0,0 +1,811 @@ +/* + * Copyright (C) 2007 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 dalvik.system; + +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledAfter; +import android.compat.annotation.UnsupportedAppUsage; +import android.system.ErrnoException; + +import dalvik.annotation.compat.VersionCodes; +import dalvik.annotation.optimization.ReachabilitySensitive; + +import libcore.io.Libcore; +import libcore.util.NonNull; +import libcore.util.Nullable; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; + +/** + * Loads DEX files. This class is meant for internal use and should not be used by applications. + * + * Applications should not instantiate this class. It will hurt performance in most cases and will + * lead to incorrect execution of bytecode in the worst case. Applications should use one of the + * standard classloaders such as {@link dalvik.system.PathClassLoader} instead. Non-static APIs + * will be removed in a future Android release. + */ +public final class DexFile { + /** + * If close is called, mCookie becomes null but the internal cookie is preserved if the close + * failed so that we can free resources in the finalizer. + */ + @UnsupportedAppUsage + @ReachabilitySensitive + private Object mCookie; + + @UnsupportedAppUsage + private Object mInternalCookie; + @UnsupportedAppUsage + private final String mFileName; + + /** + * Enforce the file passed to open DexFile to be set as read-only for apps targeting U+. This + * is to prevent files to be dynamically loaded being unexpectedly overwritten by + * malicious actors. + * + * @hide + */ + // TODO (topjohnwu@): change to @EnabledSince with U API version + @TestApi + @ChangeId + @EnabledAfter(targetSdkVersion = VersionCodes.TIRAMISU) + public static final long ENFORCE_READ_ONLY_JAVA_DCL = 218865702; + + /** + * Opens a DEX file from a given File object. + * + * @deprecated Applications should use one of the standard classloaders such + * as {@link dalvik.system.PathClassLoader} instead. This API will be removed + * in a future Android release. + */ + @Deprecated + public DexFile(File file) throws IOException { + this(file.getPath()); + } + /* + * Private version with class loader argument. + * + * @param file + * the File object referencing the actual DEX file + * @param loader + * the class loader object creating the DEX file object + * @param elements + * the temporary dex path list elements from DexPathList.makeElements + */ + DexFile(File file, ClassLoader loader, DexPathList.Element[] elements) + throws IOException { + this(file.getPath(), loader, elements); + } + + /** + * Opens a DEX file from a given filename. + * + * @deprecated Applications should use one of the standard classloaders such + * as {@link dalvik.system.PathClassLoader} instead. This API will be removed + * in a future Android release. + */ + @Deprecated + public DexFile(String fileName) throws IOException { + this(fileName, null, null); + } + + /* + * Private version with class loader argument. + * + * @param fileName + * the filename of the DEX file + * @param loader + * the class loader creating the DEX file object + * @param elements + * the temporary dex path list elements from DexPathList.makeElements + */ + DexFile(String fileName, ClassLoader loader, DexPathList.Element[] elements) + throws IOException { + mCookie = openDexFile(fileName, null, 0, loader, elements); + mInternalCookie = mCookie; + mFileName = fileName; + //System.out.println("DEX FILE cookie is " + mCookie + " fileName=" + fileName); + } + + DexFile(ByteBuffer[] bufs, ClassLoader loader, DexPathList.Element[] elements) + throws IOException { + mCookie = openInMemoryDexFiles(bufs, loader, elements); + mInternalCookie = mCookie; + mFileName = null; + } + + /** + * Opens a DEX file from a given filename, using a specified file + * to hold the optimized data. + * + * @param sourceName + * Jar or APK file with "classes.dex". + * @param outputName + * File that will hold the optimized form of the DEX data. + * @param flags + * Enable optional features. + * @param loader + * The class loader creating the DEX file object. + * @param elements + * The temporary dex path list elements from DexPathList.makeElements + */ + private DexFile(String sourceName, String outputName, int flags, ClassLoader loader, + DexPathList.Element[] elements) throws IOException { + if (outputName != null) { + try { + String parent = new File(outputName).getParent(); + if (Libcore.os.getuid() != Libcore.os.stat(parent).st_uid) { + throw new IllegalArgumentException("Optimized data directory " + parent + + " is not owned by the current user. Shared storage cannot protect" + + " your application from code injection attacks."); + } + } catch (ErrnoException ignored) { + // assume we'll fail with a more contextual error later + } + } + + mCookie = openDexFile(sourceName, outputName, flags, loader, elements); + mInternalCookie = mCookie; + mFileName = sourceName; + //System.out.println("DEX FILE cookie is " + mCookie + " sourceName=" + sourceName + " outputName=" + outputName); + } + + /** + * Open a DEX file, specifying the file in which the optimized DEX + * data should be written. If the optimized form exists and appears + * to be current, it will be used; if not, the VM will attempt to + * regenerate it. + * + * @deprecated Applications should use one of the standard classloaders such + * as {@link dalvik.system.PathClassLoader} instead. This API will be removed + * in a future Android release. + */ + @Deprecated + static public DexFile loadDex(String sourcePathName, String outputPathName, + int flags) throws IOException { + + /* + * TODO: we may want to cache previously-opened DexFile objects. + * The cache would be synchronized with close(). This would help + * us avoid mapping the same DEX more than once when an app + * decided to open it multiple times. In practice this may not + * be a real issue. + */ + return loadDex(sourcePathName, outputPathName, flags, null, null); + } + + /* + * Private version of loadDex that also takes a class loader. + * + * @param sourcePathName + * Jar or APK file with "classes.dex". (May expand this to include + * "raw DEX" in the future.) + * @param outputPathName + * File that will hold the optimized form of the DEX data. + * @param flags + * Enable optional features. (Currently none defined.) + * @param loader + * Class loader that is aloading the DEX file. + * @param elements + * The temporary dex path list elements from DexPathList.makeElements + * @return + * A new or previously-opened DexFile. + * @throws IOException + * If unable to open the source or output file. + */ + @UnsupportedAppUsage + static DexFile loadDex(String sourcePathName, String outputPathName, + int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException { + + /* + * TODO: we may want to cache previously-opened DexFile objects. + * The cache would be synchronized with close(). This would help + * us avoid mapping the same DEX more than once when an app + * decided to open it multiple times. In practice this may not + * be a real issue. + */ + return new DexFile(sourcePathName, outputPathName, flags, loader, elements); + } + + /** + * Gets the name of the (already opened) DEX file. + * + * @return the file name + * + * @deprecated Applications should use one of the standard classloaders such + * as {@link dalvik.system.PathClassLoader} instead. This API will be removed + * in a future Android release. + */ + @Deprecated + public String getName() { + return mFileName; + } + + @Override public String toString() { + if (mFileName != null) { + return getName(); + } else { + return "InMemoryDexFile[cookie=" + Arrays.toString((long[]) mCookie) + "]"; + } + } + + /** + * Closes the DEX file. + *

+ * This may not be able to release all of the resources. If classes from this DEX file are + * still resident, the DEX file can't be unmapped. In the case where we do not release all + * the resources, close is called again in the finalizer. + * + * @throws IOException + * if an I/O error occurs during closing the file, which + * normally should not happen + * + * @deprecated Applications should use one of the standard classloaders such + * as {@link dalvik.system.PathClassLoader} instead. This API will be removed + * in a future Android release. + */ + @Deprecated + public void close() throws IOException { + if (mInternalCookie != null) { + if (closeDexFile(mInternalCookie)) { + mInternalCookie = null; + } + mCookie = null; + } + } + + /** + * Loads a class. Returns the class on success, or a {@code null} reference + * on failure. + *

+ * If you are not calling this from a class loader, this is most likely not + * going to do what you want. Use {@link Class#forName(String)} instead. + *

+ * The method does not throw {@link ClassNotFoundException} if the class + * isn't found because it isn't reasonable to throw exceptions wildly every + * time a class is not found in the first DEX file we look at. + * + * @param name + * the class name, which should look like "java/lang/String" + * + * @param loader + * the class loader that tries to load the class (in most cases + * the caller of the method + * + * @return the {@link Class} object representing the class, or {@code null} + * if the class cannot be loaded + * + * @deprecated Applications should use one of the standard classloaders such + * as {@link dalvik.system.PathClassLoader} instead. This API will be removed + * in a future Android release. + */ + @Deprecated + public Class loadClass(String name, ClassLoader loader) { + String slashName = name.replace('.', '/'); + return loadClassBinaryName(slashName, loader, null); + } + + /** + * See {@link #loadClass(String, ClassLoader)}. + * + * This takes a "binary" class name to better match ClassLoader semantics. + * + * @hide + */ + @UnsupportedAppUsage + public Class loadClassBinaryName(String name, ClassLoader loader, List suppressed) { + return defineClass(name, loader, mCookie, this, suppressed); + } + + private static Class defineClass(String name, ClassLoader loader, Object cookie, + DexFile dexFile, List suppressed) { + Class result = null; + try { + result = defineClassNative(name, loader, cookie, dexFile); + } catch (NoClassDefFoundError e) { + if (suppressed != null) { + suppressed.add(e); + } + } catch (ClassNotFoundException e) { + if (suppressed != null) { + suppressed.add(e); + } + } + return result; + } + + /** + * Enumerate the names of the classes in this DEX file. + * + * @return an enumeration of names of classes contained in the DEX file, in + * the usual internal form (like "java/lang/String"). + * + * @deprecated Applications should use one of the standard classloaders such + * as {@link dalvik.system.PathClassLoader} instead. This API will be removed + * in a future Android release. + */ + @Deprecated + public Enumeration entries() { + return new DFEnum(this); + } + + /* + * Helper class. + */ + private static class DFEnum implements Enumeration { + private int mIndex; + @UnsupportedAppUsage + private String[] mNameList; + + DFEnum(DexFile df) { + mIndex = 0; + mNameList = getClassNameList(df.mCookie); + } + + public boolean hasMoreElements() { + return (mIndex < mNameList.length); + } + + public String nextElement() { + return mNameList[mIndex++]; + } + } + + /** + * Called when the class is finalized. Makes sure the DEX file is closed. + * + * @throws IOException + * if an I/O error occurs during closing the file, which + * normally should not happen + */ + @Override protected void finalize() throws Throwable { + try { + if (mInternalCookie != null && !closeDexFile(mInternalCookie)) { + throw new AssertionError("Failed to close dex file in finalizer."); + } + mInternalCookie = null; + mCookie = null; + } finally { + super.finalize(); + } + } + + + /* + * Open a DEX file. The value returned is a magic VM cookie. On + * failure, an IOException is thrown. + */ + @UnsupportedAppUsage + private static Object openDexFile(String sourceName, String outputName, int flags, + ClassLoader loader, DexPathList.Element[] elements) throws IOException { + // Use absolute paths to enable the use of relative paths when testing on host. + return openDexFileNative(new File(sourceName).getAbsolutePath(), + (outputName == null) + ? null + : new File(outputName).getAbsolutePath(), + flags, + loader, + elements); + } + + private static Object openInMemoryDexFiles(ByteBuffer[] bufs, ClassLoader loader, + DexPathList.Element[] elements) throws IOException { + // Preprocess the ByteBuffers for openInMemoryDexFilesNative. We extract + // the backing array (non-direct buffers only) and start/end positions + // so that the native method does not have to call Java methods anymore. + byte[][] arrays = new byte[bufs.length][]; + int[] starts = new int[bufs.length]; + int[] ends = new int[bufs.length]; + for (int i = 0; i < bufs.length; ++i) { + arrays[i] = bufs[i].isDirect() ? null : bufs[i].array(); + starts[i] = bufs[i].position(); + ends[i] = bufs[i].limit(); + } + return openInMemoryDexFilesNative(bufs, arrays, starts, ends, loader, elements); + } + + private static native Object openInMemoryDexFilesNative(ByteBuffer[] bufs, byte[][] arrays, + int[] starts, int[] ends, ClassLoader loader, DexPathList.Element[] elements); + + /* + * Initiates background verification of this DexFile. This is a sepearate down-call + * from openDexFile and openInMemoryDexFiles because it requires the class loader's + * DexPathList to have been initialized for its classes to be resolvable by ART. + * DexPathList will open the dex files first, finalize `dexElements` and then call this. + */ + /*package*/ void verifyInBackground(ClassLoader classLoader) { + verifyInBackgroundNative(mCookie, classLoader); + } + + private static native void verifyInBackgroundNative(Object mCookie, ClassLoader classLoader); + + /* + * Returns true if the dex file is backed by a valid oat file. + */ + @UnsupportedAppUsage + /*package*/ boolean isBackedByOatFile() { + return isBackedByOatFile(mCookie); + } + + /* + * Set the dex file as trusted: it can access hidden APIs of the platform. + */ + /*package*/ void setTrusted() { + setTrusted(mCookie); + } + + /* + * Returns true if we managed to close the dex file. + */ + private static native boolean closeDexFile(Object cookie); + private static native Class defineClassNative(String name, ClassLoader loader, Object cookie, + DexFile dexFile) + throws ClassNotFoundException, NoClassDefFoundError; + @UnsupportedAppUsage + private static native String[] getClassNameList(Object cookie); + private static native boolean isBackedByOatFile(Object cookie); + private static native void setTrusted(Object cookie); + /* + * Open a DEX file. The value returned is a magic VM cookie. On + * failure, an IOException is thrown. + */ + @UnsupportedAppUsage + private static native Object openDexFileNative(String sourceName, String outputName, int flags, + ClassLoader loader, DexPathList.Element[] elements); + + /** + * Returns true if the VM believes that the apk/jar file is out of date + * and should be passed through "dexopt" again. + * + * @param fileName the absolute path to the apk/jar file to examine. + * @return true if dexopt should be called on the file, false otherwise. + * @throws java.io.FileNotFoundException if fileName is not readable, + * not a file, or not present. + * @throws java.io.IOException if fileName is not a valid apk/jar file or + * if problems occur while parsing it. + * @throws java.lang.NullPointerException if fileName is null. + * + * @deprecated Use {@code Artd.getDexoptNeeded} instead. + */ + @Deprecated + public static native boolean isDexOptNeeded(String fileName) + throws FileNotFoundException, IOException; + + /** + * No dexopt should (or can) be done to update the apk/jar. + * + * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @Deprecated + public static final int NO_DEXOPT_NEEDED = 0; + + /** + * dex2oat should be run to update the apk/jar from scratch. + * + * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. + * + * @hide + */ + @Deprecated + public static final int DEX2OAT_FROM_SCRATCH = 1; + + /** + * dex2oat should be run to update the apk/jar because the existing code + * is out of date with respect to the boot image. + * + * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. + * + * @hide + */ + @Deprecated + public static final int DEX2OAT_FOR_BOOT_IMAGE = 2; + + /** + * dex2oat should be run to update the apk/jar because the existing code + * is out of date with respect to the target compiler filter. + * + * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @Deprecated + public static final int DEX2OAT_FOR_FILTER = 3; + + + /** + * Calls {@link #getDexOptNeeded(String, String, String, String, String, boolean, boolean)} + * with a null class loader context. + * + * TODO(ngeoffray, calin): deprecate / remove. + * @hide + */ + public static int getDexOptNeeded(String fileName, + String instructionSet, String compilerFilter, boolean newProfile, boolean downgrade) + throws FileNotFoundException, IOException { + return getDexOptNeeded( + fileName, instructionSet, compilerFilter, null, newProfile, downgrade); + } + + /** + * Returns the VM's opinion of what kind of dexopt is needed to make the + * apk/jar file up to date, where {@code targetMode} is used to indicate what + * type of compilation the caller considers up-to-date, and {@code newProfile} + * is used to indicate whether profile information has changed recently. + * + * @param fileName the absolute path to the apk/jar file to examine. + * @param instructionSet instruction set to examine + * @param compilerFilter a compiler filter to use for what a caller considers up-to-date. + * @param classLoaderContext a string encoding the class loader context the dex file + * is intended to have at runtime. + * @param newProfile flag that describes whether a profile corresponding + * to the dex file has been recently updated and should be considered + * in the state of the file. + * @param downgrade flag that describes if the purpose of dexopt is to downgrade the + * compiler filter. If set to false, will be evaluated as an upgrade request. + * @return NO_DEXOPT_NEEDED, or DEX2OAT_*. See documentation + * of the particular status code for more information on its + * meaning. Returns a positive status code if the status refers to + * the oat file in the oat location. Returns a negative status + * code if the status refers to the oat file in the odex location. + * @throws java.io.FileNotFoundException if fileName is not readable, + * not a file, or not present. + * @throws java.io.IOException if fileName is not a valid apk/jar file or + * if problems occur while parsing it. + * @throws java.lang.NullPointerException if {@code fileName} is {@code null}. + * @deprecated Use {@code Artd.getDexoptNeeded} instead. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @Deprecated + public static native int getDexOptNeeded(@NonNull String fileName, + @NonNull String instructionSet, @NonNull String compilerFilter, @Nullable String classLoaderContext, + boolean newProfile, boolean downgrade) + throws FileNotFoundException, IOException; + + /** + * Returns the status of the dex file {@code fileName}. The returned string is + * an opaque, human readable representation of the current status. The output + * is only meant for debugging and is not guaranteed to be stable across + * releases and/or devices. + * + * @hide + */ + public static native String getDexFileStatus(String fileName, String instructionSet) + throws FileNotFoundException; + + /** + * Encapsulates information about the optimizations performed on a dex file. + * + * Note that the info is only meant for debugging and is not guaranteed to be + * stable across releases and/or devices. + */ + public static final class OptimizationInfo { + // The human readable refined optimization status of the validity of the odex file. + private final String status; + // The optimization reason. The reason might be "unknown" if the + // the compiler artifacts were not annotated during optimizations. + private final String reason; + + private OptimizationInfo(String status, String reason) { + this.status = status; + this.reason = reason; + } + + /** + * Returns the human readable refined status of the validity of the odex file. + * + * @return optimization status + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public @NonNull String getStatus() { + return status; + } + + /** + * Returns the reason of a particular optimization used. + * + * @return optimization reason + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public @NonNull String getReason() { + return reason; + } + + /** + * Returns whether the dex file is verified. + */ + public boolean isVerified() { + return isVerifiedCompilerFilter(status); + } + + /** + * Returns whether the dex file is in an optimal state. Currently, this means the dex file + * is either ahead-of-time compiled with a profile or fully ahead-of-time compiled. + */ + public boolean isOptimized() { + return isOptimizedCompilerFilter(status); + } + + /** + * Returns whether the dex file is fully ahead-of-time compiled. + */ + public boolean isFullyCompiled() { + return isOptimizedCompilerFilter(status) && !isProfileGuidedCompilerFilter(status); + } + } + + /** + * Retrieves the optimization info for a dex file. + * + * @param fileName path to dex file + * @param instructionSet instruction set to get optimization info for + * @return {@link OptimizationInfo} for {@code fileName} dex file + * @throws FileNotFoundException if {@code fileName} not found + * @deprecated Applications should use {@link VMRuntime#getCurrentOptimizationStatus()}. + * System server should use {@code ArtManagerLocal.getOptimizationStatus}. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @Deprecated + public static @NonNull OptimizationInfo getDexFileOptimizationInfo( + @NonNull String fileName, @NonNull String instructionSet) throws FileNotFoundException { + String[] status = getDexFileOptimizationStatus(fileName, instructionSet); + return new OptimizationInfo(status[0], status[1]); + } + + /** + * Returns the optimization status of the dex file {@code fileName}. The returned + * array will have 2 elements which specify: + * - index 0: the level of optimizations + * - index 1: the optimization reason. The reason might be "unknown" if the + * the compiler artifacts were not annotated during optimizations. + * + * The output is only meant for debugging and is not guaranteed to be stable across + * releases and/or devices. + * + * @hide + */ + private static native String[] getDexFileOptimizationStatus( + String fileName, String instructionSet) throws FileNotFoundException; + + /** + * Returns the paths of the optimized files generated for {@code fileName}. + * If no optimized code exists the method returns {@code null}. + * + * @param fileName path to dex file + * @param instructionSet instruction set to get optimized files for + * @return paths to optimized code, or {@code null} if they do not exist + * @throws FileNotFoundException + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static native @Nullable String[] getDexFileOutputPaths(@NonNull String fileName, @NonNull String instructionSet) + throws FileNotFoundException; + + /** + * Returns whether the given filter is a valid filter. + * + * @param filter filter string + * @return whether given filter string is a valid filter + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public native static boolean isValidCompilerFilter(@NonNull String filter); + + /** + * Returns whether the given filter is based on profiles. + * + * @param filter filter string + * @return whether given filter string is based on profiles + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public native static boolean isProfileGuidedCompilerFilter(@NonNull String filter); + + /** + * Returns whether the given filter includes verification. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public native static boolean isVerifiedCompilerFilter(@NonNull String filter); + + /** + * Returns whether the given filter includes AOT compilation. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public native static boolean isOptimizedCompilerFilter(@NonNull String filter); + + /** + * Returns whether JAR/DEX files' read-only status is enforced. + * + * @see #ENFORCE_READ_ONLY_JAVA_DCL + * @hide + */ + @TestApi + public static native boolean isReadOnlyJavaDclEnforced(); + + /** + * Returns the version of the compiler filter that is not based on profiles. + * If the input is not a valid filter, or the filter is already not based on + * profiles, this returns the input. + * + * @param filter filter string + * @return version of the compiler filter that is not based on profiles + * + * @hide + */ + public native static String getNonProfileGuidedCompilerFilter(String filter); + + /** + * Returns the version of the compiler filter that is suitable for safe mode. + * If the input is not a valid filter, or the filter is already suitable for + * safe mode, this returns the input. + * + * @param filter filter string + * @return version of the compiler filter that is suitable for safe mode + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public native static @NonNull String getSafeModeCompilerFilter(@NonNull String filter); + + /** + * Returns the static file size of the original dex file. + * The original size of the uncompressed dex file is returned. + * On device the dex file may be compressed or embedded in some other + * file (e.g. oat) in a platform implementation dependent manner. This + * method abstracts away from those details and provides an efficient + * implementation given that the dex file in question has already been + * uncompressed, extracted, and/or loaded by the runtime as appropriate. + *

+ * In the case of multidex, returns the sum of the original uncompressed + * multidex entry file sizes. + * + * @hide + */ + public long getStaticSizeOfDexFile() { + return getStaticSizeOfDexFile(mCookie); + } + + private static native long getStaticSizeOfDexFile(Object cookie); +} -- Gitee From d29f70cb2cb32fea7878fb227f2834e1ef6fcc29 Mon Sep 17 00:00:00 2001 From: roger2015 Date: Tue, 11 Mar 2025 20:16:43 +0800 Subject: [PATCH 2/2] fix 996hezi --- aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java | 3 ++- aosp/vendor/isula/packages.mk | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java b/aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java index 8d73604e0..119736b33 100644 --- a/aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java +++ b/aosp/libcore/dalvik/src/main/java/dalvik/system/DexFile.java @@ -23,6 +23,7 @@ import android.annotation.TestApi; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; +import android.compat.annotation.Disabled; import android.system.ErrnoException; import dalvik.annotation.compat.VersionCodes; @@ -72,7 +73,7 @@ public final class DexFile { // TODO (topjohnwu@): change to @EnabledSince with U API version @TestApi @ChangeId - @EnabledAfter(targetSdkVersion = VersionCodes.TIRAMISU) + @Disabled public static final long ENFORCE_READ_ONLY_JAVA_DCL = 218865702; /** diff --git a/aosp/vendor/isula/packages.mk b/aosp/vendor/isula/packages.mk index 88704fef7..569027e0b 100644 --- a/aosp/vendor/isula/packages.mk +++ b/aosp/vendor/isula/packages.mk @@ -122,3 +122,5 @@ PRODUCT_PACKAGES += \ default_enc_params.json \ media_codecs_c2.xml \ +# tools +PRODUCT_PACKAGES += curl \ No newline at end of file -- Gitee