Move all API database ammendmends to pre-generation. Bug: b/510269018 Change-Id: I41764b10ffb47b4693b18b65251a37fa93e82063
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelDatabaseHelper.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelDatabaseHelper.java index 6d112c1..9785da9 100644 --- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelDatabaseHelper.java +++ b/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelDatabaseHelper.java
@@ -4,14 +4,8 @@ package com.android.tools.r8.androidapi; -import com.android.tools.r8.graph.DexItemFactory; -import com.android.tools.r8.graph.DexProto; -import com.android.tools.r8.graph.DexReference; -import com.android.tools.r8.graph.DexType; -import com.android.tools.r8.utils.AndroidApiLevel; import java.util.HashSet; import java.util.Set; -import java.util.function.BiConsumer; public class AndroidApiLevelDatabaseHelper { @@ -29,741 +23,4 @@ "android.adservices.ondevicepersonalization.FederatedComputeScheduleResponse"); return notModeledTypes; } - - public static Set<String> notModeledFields() { - // The fields below are known not to be modeled by any api-versions. - Set<String> notModeledFields = new HashSet<>(); - notModeledFields.add("int android.app.appsearch.AppSearchResult.RESULT_DENIED"); - notModeledFields.add("int android.app.appsearch.AppSearchResult.RESULT_RATE_LIMITED"); - - notModeledFields.add( - "int android.adservices.adselection.ReportEventRequest.FLAG_REPORTING_DESTINATION_COMPONENT_SELLER"); - notModeledFields.add( - "int android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.FEATURE_DISABLED"); - notModeledFields.add( - "int android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.FEATURE_ENABLED"); - notModeledFields.add( - "int android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.FEATURE_UNSUPPORTED"); - notModeledFields.add( - "int android.adservices.ondevicepersonalization.InferenceInput$Params.MODEL_TYPE_EXECUTORCH"); - return notModeledFields; - } - - public static Set<String> notModeledMethods() { - // The methods below are known not to be modeled by any api-versions. - Set<String> notModelledMethods = new HashSet<>(); - notModelledMethods.add( - "void android.adservices.customaudience.CustomAudienceManager.scheduleCustomAudienceUpdate(android.adservices.customaudience.ScheduleCustomAudienceUpdateRequest," - + " java.util.concurrent.Executor," - + " android.adservices.common.AdServicesOutcomeReceiver)"); - notModelledMethods.add( - "android.adservices.ondevicepersonalization.InferenceOutput$Builder" - + " android.adservices.ondevicepersonalization.InferenceOutput$Builder.setData(byte[])"); - notModelledMethods.add( - "android.adservices.common.AdTechIdentifier" - + " android.adservices.adselection.AdSelectionOutcome.getWinningSeller()"); - notModelledMethods.add( - "void android.adservices.ondevicepersonalization.FederatedComputeScheduler.schedule(android.adservices.ondevicepersonalization.FederatedComputeScheduleRequest," - + " java.util.concurrent.Executor, android.os.OutcomeReceiver)"); - - notModelledMethods.add( - "byte[] android.adservices.ondevicepersonalization.InferenceOutput.getData()"); - notModelledMethods.add( - "byte[] android.adservices.ondevicepersonalization.InferenceInput.getData()"); - notModelledMethods.add( - "void android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.queryFeatureAvailability(java.lang.String," - + " java.util.concurrent.Executor, android.os.OutcomeReceiver)"); - notModelledMethods.add( - "void android.adservices.ondevicepersonalization.InferenceInput$Builder.<init>(android.adservices.ondevicepersonalization.InferenceInput$Params," - + " byte[])"); - notModelledMethods.add( - "android.adservices.ondevicepersonalization.InferenceInput$Builder" - + " android.adservices.ondevicepersonalization.InferenceInput$Builder.setInputData(byte[])"); - return notModelledMethods; - } - - static void visitAdditionalKnownApiReferences( - DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { - addStringBuilderAndBufferMethods(factory, apiLevelConsumer); - addConcurrentKeySetViewMethods(factory, apiLevelConsumer); - addNfcMethods(factory, apiLevelConsumer); - addWebkitCookieSyncManagerMethods(factory, apiLevelConsumer); - addChronoTimeMethods(factory, apiLevelConsumer); - addUnsafeMethods(factory, apiLevelConsumer); - } - - private static void addStringBuilderAndBufferMethods( - DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { - // StringBuilder and StringBuffer lack api definitions for the exact same methods in - // api-versions.xml. See b/216587554 for related error. - for (DexType type : new DexType[] {factory.stringBuilderType, factory.stringBufferType}) { - apiLevelConsumer.accept( - factory.createMethod(type, factory.createProto(factory.intType), "capacity"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, factory.createProto(factory.intType, factory.intType), "codePointAt"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, factory.createProto(factory.intType, factory.intType), "codePointBefore"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, - factory.createProto(factory.intType, factory.intType, factory.intType), - "codePointCount"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, factory.createProto(factory.voidType, factory.intType), "ensureCapacity"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, - factory.createProto( - factory.voidType, - factory.intType, - factory.intType, - factory.charArrayType, - factory.intType), - "getChars"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, factory.createProto(factory.intType, factory.stringType), "indexOf"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, - factory.createProto(factory.intType, factory.stringType, factory.intType), - "indexOf"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, factory.createProto(factory.intType, factory.stringType), "lastIndexOf"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, - factory.createProto(factory.intType, factory.stringType, factory.intType), - "lastIndexOf"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, - factory.createProto(factory.intType, factory.intType, factory.intType), - "offsetByCodePoints"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, - factory.createProto(factory.voidType, factory.intType, factory.charType), - "setCharAt"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, factory.createProto(factory.voidType, factory.intType), "setLength"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, factory.createProto(factory.stringType, factory.intType), "substring"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod( - type, - factory.createProto(factory.stringType, factory.intType, factory.intType), - "substring"), - AndroidApiLevel.B); - apiLevelConsumer.accept( - factory.createMethod(type, factory.createProto(factory.voidType), "trimToSize"), - AndroidApiLevel.B); - } - } - - private static void addConcurrentKeySetViewMethods( - DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { - // KeysetView.getMap was also added in N (24). - apiLevelConsumer.accept( - factory.createMethod( - factory.concurrentHashMapKeySetViewType, - factory.createProto(factory.concurrentHashMapType), - "getMap"), - AndroidApiLevel.N); - } - - private static void addNfcMethods( - DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { - String[] nfcClasses = - new String[] { - "Landroid/nfc/tech/Ndef;", - "Landroid/nfc/tech/NfcA;", - "Landroid/nfc/tech/NfcB;", - "Landroid/nfc/tech/NfcBarcode;", - "Landroid/nfc/tech/NfcF;", - "Landroid/nfc/tech/NdefFormatable;", - "Landroid/nfc/tech/IsoDep;", - "Landroid/nfc/tech/MifareClassic;", - "Landroid/nfc/tech/MifareUltralight;", - "Landroid/nfc/tech/NfcV;" - }; - DexType tagType = factory.createType("Landroid/nfc/Tag;"); - // Seems like all methods are available from api level G_MR1 but we choose K since some of these - // classes are introduced at 17. - for (String nfcClass : nfcClasses) { - DexType nfcClassType = factory.createType(nfcClass); - apiLevelConsumer.accept( - factory.createMethod( - nfcClassType, factory.createProto(factory.booleanType), "isConnected"), - AndroidApiLevel.K); - apiLevelConsumer.accept( - factory.createMethod(nfcClassType, factory.createProto(tagType), "getTag"), - AndroidApiLevel.K); - apiLevelConsumer.accept( - factory.createMethod(nfcClassType, factory.createProto(factory.voidType), "close"), - AndroidApiLevel.K); - apiLevelConsumer.accept( - factory.createMethod(nfcClassType, factory.createProto(factory.voidType), "connect"), - AndroidApiLevel.K); - } - } - - private static void addWebkitCookieSyncManagerMethods( - DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { - // All of these are added in android.jar from at least 14. - DexType cookieSyncManager = factory.createType("Landroid/webkit/CookieSyncManager;"); - DexProto voidProto = factory.createProto(factory.voidType); - for (String methodName : new String[] {"sync", "resetSync", "startSync", "stopSync", "run"}) { - apiLevelConsumer.accept( - factory.createMethod(cookieSyncManager, voidProto, methodName), AndroidApiLevel.I); - } - } - - private static void addChronoTimeMethods( - DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { - DexType valueRangeType = factory.createType("Ljava/time/temporal/ValueRange;"); - DexType chronoLocalDateType = factory.createType("Ljava/time/chrono/ChronoLocalDate;"); - DexType temporalType = factory.createType("Ljava/time/temporal/Temporal;"); - DexType temporalFieldType = factory.createType("Ljava/time/temporal/TemporalField;"); - DexType temporalUnitType = factory.createType("Ljava/time/temporal/TemporalUnit;"); - DexType temporalAmountType = factory.createType("Ljava/time/temporal/TemporalAmount;"); - DexType temporalAdjusterType = factory.createType("Ljava/time/temporal/TemporalAdjuster;"); - - // All of these classes was added in 26. - String[] timeClasses = - new String[] { - "Ljava/time/chrono/JapaneseDate;", - "Ljava/time/chrono/MinguoDate;", - "Ljava/time/chrono/HijrahDate;", - "Ljava/time/chrono/ThaiBuddhistDate;" - }; - for (String timeClass : timeClasses) { - DexType timeType = factory.createType(timeClass); - // int lengthOfMonth() - apiLevelConsumer.accept( - factory.createMethod(timeType, factory.createProto(factory.intType), "lengthOfMonth"), - AndroidApiLevel.O); - // int lengthOfYear() - apiLevelConsumer.accept( - factory.createMethod(timeType, factory.createProto(factory.intType), "lengthOfYear"), - AndroidApiLevel.O); - // boolean isSupported(java.time.temporal.TemporalField) - apiLevelConsumer.accept( - factory.createMethod( - timeType, factory.createProto(factory.booleanType, temporalFieldType), "isSupported"), - AndroidApiLevel.O); - // java.time.temporal.ValueRange range(java.time.temporal.TemporalField) - apiLevelConsumer.accept( - factory.createMethod( - timeType, factory.createProto(valueRangeType, temporalFieldType), "range"), - AndroidApiLevel.O); - // long getLong(java.time.temporal.TemporalField) - apiLevelConsumer.accept( - factory.createMethod( - timeType, factory.createProto(factory.longType, temporalFieldType), "getLong"), - AndroidApiLevel.O); - // java.time.chrono.ChronoLocalDateTime atTime(java.time.LocalTime) - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto( - factory.createType("Ljava/time/chrono/ChronoLocalDateTime;"), - factory.createType("Ljava/time/LocalTime;")), - "atTime"), - AndroidApiLevel.O); - // java.time.chrono.ChronoPeriod - // java.time.chrono.JapaneseDate.until(java.time.chrono.ChronoLocalDate) - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto( - factory.createType("Ljava/time/chrono/ChronoPeriod;"), chronoLocalDateType), - "until"), - AndroidApiLevel.O); - // long toEpochDay() - apiLevelConsumer.accept( - factory.createMethod(timeType, factory.createProto(factory.longType), "toEpochDay"), - AndroidApiLevel.O); - // long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit) - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto(factory.longType, temporalType, temporalUnitType), - "until"), - AndroidApiLevel.O); - - // java.time.chrono.Era getEra() - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto(factory.createType("Ljava/time/chrono/Era;")), - "getEra"), - AndroidApiLevel.O); - // java.time.chrono.Chronology getChronology() - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto(factory.createType("Ljava/time/chrono/Chronology;")), - "getChronology"), - AndroidApiLevel.O); - DexType[] returnTypesForModificationMethods = - new DexType[] {chronoLocalDateType, temporalType}; - for (DexType returnType : returnTypesForModificationMethods) { - // [returnType] minus(long, java.time.temporal.TemporalUnit) - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto(returnType, factory.longType, temporalUnitType), - "minus"), - AndroidApiLevel.O); - // [returnType] minus(java.time.temporal.TemporalAmount) - apiLevelConsumer.accept( - factory.createMethod( - timeType, factory.createProto(returnType, temporalAmountType), "minus"), - AndroidApiLevel.O); - // [returnType] plus(long, java.time.temporal.TemporalUnit) - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto(returnType, factory.longType, temporalUnitType), - "plus"), - AndroidApiLevel.O); - // [returnType] plus(java.time.temporal.TemporalAmount) - apiLevelConsumer.accept( - factory.createMethod( - timeType, factory.createProto(returnType, temporalAmountType), "plus"), - AndroidApiLevel.O); - // [returnType] with(java.time.temporal.TemporalField, long) - apiLevelConsumer.accept( - factory.createMethod( - timeType, - factory.createProto(returnType, temporalFieldType, factory.longType), - "with"), - AndroidApiLevel.O); - // [returnType] with(java.time.temporal.TemporalAdjuster) - apiLevelConsumer.accept( - factory.createMethod( - timeType, factory.createProto(returnType, temporalAdjusterType), "with"), - AndroidApiLevel.O); - } - } - // boolean java.time.chrono.HijrahDate.isLeapYear() - apiLevelConsumer.accept( - factory.createMethod( - factory.createType("Ljava/time/chrono/HijrahDate;"), - factory.createProto(factory.booleanType), - "isLeapYear"), - AndroidApiLevel.O); - } - - public static void addUnsafeMethods( - DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { - // If this assert fails then check these things before updating the assert: - // * Check if libcore/ojluni/src/main/java/sun/misc/Unsafe.java has new public methods, - // including new overloads. - // * If so, add the new methods here - // (and to SunMiscUnsafeApiTest but it will fail if you don't). - // * Verify that no existing methods have been removed. - assert AndroidApiLevel.LATEST.isEqualTo(AndroidApiLevel.CINNAMON_BUN); - - AndroidApiLevel always = AndroidApiLevel.B; - - apiLevelConsumer.accept(factory.sunMiscUnsafeType, always); - - // Fields - apiLevelConsumer.accept( - factory.createField(factory.sunMiscUnsafeType, factory.intType, "INVALID_FIELD_OFFSET"), - AndroidApiLevel.N); - - // Methods - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, factory.createProto(factory.intType), "addressSize"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.objectType, factory.classType), - "allocateInstance"), - AndroidApiLevel.J); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.longType, factory.longType), - "allocateMemory"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.intType, factory.classType), - "arrayBaseOffset"), - always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.intType, factory.classType), - "arrayIndexScale"), - always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.compareAndSwapInt, always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.compareAndSwapLong, always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.compareAndSwapObject, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.longType, factory.longType, factory.longType), - "copyMemory"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, - factory.objectType, - factory.longType, - factory.longType, - factory.longType), - "copyMemoryFromPrimitiveArray"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, - factory.longType, - factory.objectType, - factory.longType, - factory.longType), - "copyMemoryToPrimitiveArray"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType), - "freeMemory"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, factory.createProto(factory.voidType), "fullFence"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.intType, factory.objectType, factory.longType, factory.intType), - "getAndAddInt"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.longType, factory.objectType, factory.longType, factory.longType), - "getAndAddLong"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.intType, factory.objectType, factory.longType, factory.intType), - "getAndSetInt"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.longType, factory.objectType, factory.longType, factory.longType), - "getAndSetLong"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.objectType, factory.objectType, factory.longType, factory.objectType), - "getAndSetObject"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.booleanType, factory.objectType, factory.longType), - "getBoolean"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.byteType, factory.longType), - "getByte"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.byteType, factory.objectType, factory.longType), - "getByte"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.charType, factory.longType), - "getChar"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.charType, factory.objectType, factory.longType), - "getChar"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.doubleType, factory.longType), - "getDouble"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.doubleType, factory.objectType, factory.longType), - "getDouble"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.floatType, factory.longType), - "getFloat"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.floatType, factory.objectType, factory.longType), - "getFloat"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.intType, factory.longType), - "getInt"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.intType, factory.objectType, factory.longType), - "getInt"), - always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.getIntVolatile, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.longType, factory.longType), - "getLong"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.longType, factory.objectType, factory.longType), - "getLong"), - always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.getLongVolatile, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.objectType, factory.objectType, factory.longType), - "getObject"), - always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.getObjectVolatile, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.shortType, factory.longType), - "getShort"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.shortType, factory.objectType, factory.longType), - "getShort"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, factory.createProto(factory.sunMiscUnsafeType), "getUnsafe"), - always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, factory.createProto(factory.voidType), "loadFence"), - AndroidApiLevel.N); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.objectFieldOffset, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, factory.createProto(factory.intType), "pageSize"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.booleanType, factory.longType), - "park"), - always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.booleanType), - "putBoolean"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType, factory.byteType), - "putByte"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.byteType), - "putByte"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType, factory.charType), - "putChar"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.charType), - "putChar"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType, factory.doubleType), - "putDouble"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.doubleType), - "putDouble"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType, factory.floatType), - "putFloat"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.floatType), - "putFloat"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType, factory.intType), - "putInt"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.intType), - "putInt"), - always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.putIntVolatile, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType, factory.longType), - "putLong"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.longType), - "putLong"), - always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.putLongVolatile, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.objectType), - "putObject"), - always); - apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.putObjectVolatile, always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.intType), - "putOrderedInt"), - always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.longType), - "putOrderedLong"), - always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.objectType), - "putOrderedObject"), - always); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.longType, factory.shortType), - "putShort"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.objectType, factory.longType, factory.shortType), - "putShort"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto( - factory.voidType, factory.longType, factory.longType, factory.byteType), - "setMemory"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, factory.createProto(factory.voidType), "storeFence"), - AndroidApiLevel.N); - apiLevelConsumer.accept( - factory.createMethod( - factory.sunMiscUnsafeType, - factory.createProto(factory.voidType, factory.objectType), - "unpark"), - always); - } }
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java index 0c73f89..4f2602d 100644 --- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java +++ b/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java
@@ -48,8 +48,6 @@ ImmutableList.Builder<AndroidApiForHashingReference> builder = ImmutableList.builder(); BiConsumer<DexReference, AndroidApiLevel> addItemToList = ConsumerUtils.andThen(AndroidApiForHashingReference::create, builder::add); - AndroidApiLevelDatabaseHelper.visitAdditionalKnownApiReferences( - appView.dexItemFactory(), addItemToList); appView .options() .apiModelingOptions()
diff --git a/src/test/java/com/android/tools/r8/androidapi/AndroidApiLevelDatabaseTestHelper.java b/src/test/java/com/android/tools/r8/androidapi/AndroidApiLevelDatabaseTestHelper.java new file mode 100644 index 0000000..e73b40a --- /dev/null +++ b/src/test/java/com/android/tools/r8/androidapi/AndroidApiLevelDatabaseTestHelper.java
@@ -0,0 +1,754 @@ +// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.androidapi; + +import com.android.tools.r8.graph.DexItemFactory; +import com.android.tools.r8.graph.DexProto; +import com.android.tools.r8.graph.DexReference; +import com.android.tools.r8.graph.DexType; +import com.android.tools.r8.utils.AndroidApiLevel; +import java.util.HashSet; +import java.util.Set; +import java.util.function.BiConsumer; + +public class AndroidApiLevelDatabaseTestHelper { + + public static Set<String> notModeledFields() { + // The fields below are known not to be modeled by any api-versions. + Set<String> notModeledFields = new HashSet<>(); + notModeledFields.add("int android.app.appsearch.AppSearchResult.RESULT_DENIED"); + notModeledFields.add("int android.app.appsearch.AppSearchResult.RESULT_RATE_LIMITED"); + + notModeledFields.add( + "int android.adservices.adselection.ReportEventRequest.FLAG_REPORTING_DESTINATION_COMPONENT_SELLER"); + notModeledFields.add( + "int android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.FEATURE_DISABLED"); + notModeledFields.add( + "int android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.FEATURE_ENABLED"); + notModeledFields.add( + "int android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.FEATURE_UNSUPPORTED"); + notModeledFields.add( + "int android.adservices.ondevicepersonalization.InferenceInput$Params.MODEL_TYPE_EXECUTORCH"); + return notModeledFields; + } + + public static Set<String> notModeledMethods() { + // The methods below are known not to be modeled by any api-versions. + Set<String> notModelledMethods = new HashSet<>(); + notModelledMethods.add( + "void android.adservices.customaudience.CustomAudienceManager.scheduleCustomAudienceUpdate(android.adservices.customaudience.ScheduleCustomAudienceUpdateRequest," + + " java.util.concurrent.Executor," + + " android.adservices.common.AdServicesOutcomeReceiver)"); + notModelledMethods.add( + "android.adservices.ondevicepersonalization.InferenceOutput$Builder" + + " android.adservices.ondevicepersonalization.InferenceOutput$Builder.setData(byte[])"); + notModelledMethods.add( + "android.adservices.common.AdTechIdentifier" + + " android.adservices.adselection.AdSelectionOutcome.getWinningSeller()"); + notModelledMethods.add( + "void android.adservices.ondevicepersonalization.FederatedComputeScheduler.schedule(android.adservices.ondevicepersonalization.FederatedComputeScheduleRequest," + + " java.util.concurrent.Executor, android.os.OutcomeReceiver)"); + + notModelledMethods.add( + "byte[] android.adservices.ondevicepersonalization.InferenceOutput.getData()"); + notModelledMethods.add( + "byte[] android.adservices.ondevicepersonalization.InferenceInput.getData()"); + notModelledMethods.add( + "void android.adservices.ondevicepersonalization.OnDevicePersonalizationManager.queryFeatureAvailability(java.lang.String," + + " java.util.concurrent.Executor, android.os.OutcomeReceiver)"); + notModelledMethods.add( + "void android.adservices.ondevicepersonalization.InferenceInput$Builder.<init>(android.adservices.ondevicepersonalization.InferenceInput$Params," + + " byte[])"); + notModelledMethods.add( + "android.adservices.ondevicepersonalization.InferenceInput$Builder" + + " android.adservices.ondevicepersonalization.InferenceInput$Builder.setInputData(byte[])"); + return notModelledMethods; + } + + public static void visitAdditionalKnownApiReferences( + DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { + addStringBuilderAndBufferMethods(factory, apiLevelConsumer); + addConcurrentKeySetViewMethods(factory, apiLevelConsumer); + addNfcMethods(factory, apiLevelConsumer); + addWebkitCookieSyncManagerMethods(factory, apiLevelConsumer); + addChronoTimeMethods(factory, apiLevelConsumer); + addUnsafeMethods(factory, apiLevelConsumer); + } + + private static void addStringBuilderAndBufferMethods( + DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { + // StringBuilder and StringBuffer lack api definitions for the exact same methods in + // api-versions.xml. See b/216587554 for related error. + for (DexType type : new DexType[] {factory.stringBuilderType, factory.stringBufferType}) { + apiLevelConsumer.accept( + factory.createMethod(type, factory.createProto(factory.intType), "capacity"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, factory.createProto(factory.intType, factory.intType), "codePointAt"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, factory.createProto(factory.intType, factory.intType), "codePointBefore"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, + factory.createProto(factory.intType, factory.intType, factory.intType), + "codePointCount"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, factory.createProto(factory.voidType, factory.intType), "ensureCapacity"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, + factory.createProto( + factory.voidType, + factory.intType, + factory.intType, + factory.charArrayType, + factory.intType), + "getChars"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, factory.createProto(factory.intType, factory.stringType), "indexOf"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, + factory.createProto(factory.intType, factory.stringType, factory.intType), + "indexOf"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, factory.createProto(factory.intType, factory.stringType), "lastIndexOf"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, + factory.createProto(factory.intType, factory.stringType, factory.intType), + "lastIndexOf"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, + factory.createProto(factory.intType, factory.intType, factory.intType), + "offsetByCodePoints"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, + factory.createProto(factory.voidType, factory.intType, factory.charType), + "setCharAt"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, factory.createProto(factory.voidType, factory.intType), "setLength"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, factory.createProto(factory.stringType, factory.intType), "substring"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod( + type, + factory.createProto(factory.stringType, factory.intType, factory.intType), + "substring"), + AndroidApiLevel.B); + apiLevelConsumer.accept( + factory.createMethod(type, factory.createProto(factory.voidType), "trimToSize"), + AndroidApiLevel.B); + } + } + + private static void addConcurrentKeySetViewMethods( + DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { + // KeysetView.getMap was also added in N (24). + apiLevelConsumer.accept( + factory.createMethod( + factory.concurrentHashMapKeySetViewType, + factory.createProto(factory.concurrentHashMapType), + "getMap"), + AndroidApiLevel.N); + } + + private static void addNfcMethods( + DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { + String[] nfcClasses = + new String[] { + "Landroid/nfc/tech/Ndef;", + "Landroid/nfc/tech/NfcA;", + "Landroid/nfc/tech/NfcB;", + "Landroid/nfc/tech/NfcBarcode;", + "Landroid/nfc/tech/NfcF;", + "Landroid/nfc/tech/NdefFormatable;", + "Landroid/nfc/tech/IsoDep;", + "Landroid/nfc/tech/MifareClassic;", + "Landroid/nfc/tech/MifareUltralight;", + "Landroid/nfc/tech/NfcV;" + }; + DexType tagType = factory.createType("Landroid/nfc/Tag;"); + // Seems like all methods are available from api level G_MR1 but we choose K since some of these + // classes are introduced at 17. + for (String nfcClass : nfcClasses) { + DexType nfcClassType = factory.createType(nfcClass); + apiLevelConsumer.accept( + factory.createMethod( + nfcClassType, factory.createProto(factory.booleanType), "isConnected"), + AndroidApiLevel.K); + apiLevelConsumer.accept( + factory.createMethod(nfcClassType, factory.createProto(tagType), "getTag"), + AndroidApiLevel.K); + apiLevelConsumer.accept( + factory.createMethod(nfcClassType, factory.createProto(factory.voidType), "close"), + AndroidApiLevel.K); + apiLevelConsumer.accept( + factory.createMethod(nfcClassType, factory.createProto(factory.voidType), "connect"), + AndroidApiLevel.K); + } + } + + private static void addWebkitCookieSyncManagerMethods( + DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { + // All of these are added in android.jar from at least 14. + DexType cookieSyncManager = factory.createType("Landroid/webkit/CookieSyncManager;"); + DexProto voidProto = factory.createProto(factory.voidType); + for (String methodName : new String[] {"sync", "resetSync", "startSync", "stopSync", "run"}) { + apiLevelConsumer.accept( + factory.createMethod(cookieSyncManager, voidProto, methodName), AndroidApiLevel.I); + } + } + + private static void addChronoTimeMethods( + DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { + DexType valueRangeType = factory.createType("Ljava/time/temporal/ValueRange;"); + DexType chronoLocalDateType = factory.createType("Ljava/time/chrono/ChronoLocalDate;"); + DexType temporalType = factory.createType("Ljava/time/temporal/Temporal;"); + DexType temporalFieldType = factory.createType("Ljava/time/temporal/TemporalField;"); + DexType temporalUnitType = factory.createType("Ljava/time/temporal/TemporalUnit;"); + DexType temporalAmountType = factory.createType("Ljava/time/temporal/TemporalAmount;"); + DexType temporalAdjusterType = factory.createType("Ljava/time/temporal/TemporalAdjuster;"); + + // All of these classes was added in 26. + String[] timeClasses = + new String[] { + "Ljava/time/chrono/JapaneseDate;", + "Ljava/time/chrono/MinguoDate;", + "Ljava/time/chrono/HijrahDate;", + "Ljava/time/chrono/ThaiBuddhistDate;" + }; + for (String timeClass : timeClasses) { + DexType timeType = factory.createType(timeClass); + // int lengthOfMonth() + apiLevelConsumer.accept( + factory.createMethod(timeType, factory.createProto(factory.intType), "lengthOfMonth"), + AndroidApiLevel.O); + // int lengthOfYear() + apiLevelConsumer.accept( + factory.createMethod(timeType, factory.createProto(factory.intType), "lengthOfYear"), + AndroidApiLevel.O); + // boolean isSupported(java.time.temporal.TemporalField) + apiLevelConsumer.accept( + factory.createMethod( + timeType, factory.createProto(factory.booleanType, temporalFieldType), "isSupported"), + AndroidApiLevel.O); + // java.time.temporal.ValueRange range(java.time.temporal.TemporalField) + apiLevelConsumer.accept( + factory.createMethod( + timeType, factory.createProto(valueRangeType, temporalFieldType), "range"), + AndroidApiLevel.O); + // long getLong(java.time.temporal.TemporalField) + apiLevelConsumer.accept( + factory.createMethod( + timeType, factory.createProto(factory.longType, temporalFieldType), "getLong"), + AndroidApiLevel.O); + // java.time.chrono.ChronoLocalDateTime atTime(java.time.LocalTime) + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto( + factory.createType("Ljava/time/chrono/ChronoLocalDateTime;"), + factory.createType("Ljava/time/LocalTime;")), + "atTime"), + AndroidApiLevel.O); + // java.time.chrono.ChronoPeriod + // java.time.chrono.JapaneseDate.until(java.time.chrono.ChronoLocalDate) + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto( + factory.createType("Ljava/time/chrono/ChronoPeriod;"), chronoLocalDateType), + "until"), + AndroidApiLevel.O); + // long toEpochDay() + apiLevelConsumer.accept( + factory.createMethod(timeType, factory.createProto(factory.longType), "toEpochDay"), + AndroidApiLevel.O); + // long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit) + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto(factory.longType, temporalType, temporalUnitType), + "until"), + AndroidApiLevel.O); + + // java.time.chrono.Era getEra() + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto(factory.createType("Ljava/time/chrono/Era;")), + "getEra"), + AndroidApiLevel.O); + // java.time.chrono.Chronology getChronology() + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto(factory.createType("Ljava/time/chrono/Chronology;")), + "getChronology"), + AndroidApiLevel.O); + DexType[] returnTypesForModificationMethods = + new DexType[] {chronoLocalDateType, temporalType}; + for (DexType returnType : returnTypesForModificationMethods) { + // [returnType] minus(long, java.time.temporal.TemporalUnit) + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto(returnType, factory.longType, temporalUnitType), + "minus"), + AndroidApiLevel.O); + // [returnType] minus(java.time.temporal.TemporalAmount) + apiLevelConsumer.accept( + factory.createMethod( + timeType, factory.createProto(returnType, temporalAmountType), "minus"), + AndroidApiLevel.O); + // [returnType] plus(long, java.time.temporal.TemporalUnit) + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto(returnType, factory.longType, temporalUnitType), + "plus"), + AndroidApiLevel.O); + // [returnType] plus(java.time.temporal.TemporalAmount) + apiLevelConsumer.accept( + factory.createMethod( + timeType, factory.createProto(returnType, temporalAmountType), "plus"), + AndroidApiLevel.O); + // [returnType] with(java.time.temporal.TemporalField, long) + apiLevelConsumer.accept( + factory.createMethod( + timeType, + factory.createProto(returnType, temporalFieldType, factory.longType), + "with"), + AndroidApiLevel.O); + // [returnType] with(java.time.temporal.TemporalAdjuster) + apiLevelConsumer.accept( + factory.createMethod( + timeType, factory.createProto(returnType, temporalAdjusterType), "with"), + AndroidApiLevel.O); + } + } + // boolean java.time.chrono.HijrahDate.isLeapYear() + apiLevelConsumer.accept( + factory.createMethod( + factory.createType("Ljava/time/chrono/HijrahDate;"), + factory.createProto(factory.booleanType), + "isLeapYear"), + AndroidApiLevel.O); + } + + public static void addUnsafeMethods( + DexItemFactory factory, BiConsumer<DexReference, AndroidApiLevel> apiLevelConsumer) { + // If this assert fails then check these things before updating the assert: + // * Check if libcore/ojluni/src/main/java/sun/misc/Unsafe.java has new public methods, + // including new overloads. + // * If so, add the new methods here + // (and to SunMiscUnsafeApiTest but it will fail if you don't). + // * Verify that no existing methods have been removed. + assert AndroidApiLevel.LATEST.isEqualTo(AndroidApiLevel.CINNAMON_BUN); + + AndroidApiLevel always = AndroidApiLevel.B; + + apiLevelConsumer.accept(factory.sunMiscUnsafeType, always); + + // Fields + apiLevelConsumer.accept( + factory.createField(factory.sunMiscUnsafeType, factory.intType, "INVALID_FIELD_OFFSET"), + AndroidApiLevel.N); + + // Methods + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, factory.createProto(factory.intType), "addressSize"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.objectType, factory.classType), + "allocateInstance"), + AndroidApiLevel.J); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.longType, factory.longType), + "allocateMemory"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.intType, factory.classType), + "arrayBaseOffset"), + always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.intType, factory.classType), + "arrayIndexScale"), + always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.compareAndSwapInt, always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.compareAndSwapLong, always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.compareAndSwapObject, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.longType, factory.longType, factory.longType), + "copyMemory"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, + factory.objectType, + factory.longType, + factory.longType, + factory.longType), + "copyMemoryFromPrimitiveArray"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, + factory.longType, + factory.objectType, + factory.longType, + factory.longType), + "copyMemoryToPrimitiveArray"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType), + "freeMemory"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, factory.createProto(factory.voidType), "fullFence"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.intType, factory.objectType, factory.longType, factory.intType), + "getAndAddInt"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.longType, factory.objectType, factory.longType, factory.longType), + "getAndAddLong"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.intType, factory.objectType, factory.longType, factory.intType), + "getAndSetInt"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.longType, factory.objectType, factory.longType, factory.longType), + "getAndSetLong"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.objectType, factory.objectType, factory.longType, factory.objectType), + "getAndSetObject"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.booleanType, factory.objectType, factory.longType), + "getBoolean"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.byteType, factory.longType), + "getByte"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.byteType, factory.objectType, factory.longType), + "getByte"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.charType, factory.longType), + "getChar"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.charType, factory.objectType, factory.longType), + "getChar"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.doubleType, factory.longType), + "getDouble"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.doubleType, factory.objectType, factory.longType), + "getDouble"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.floatType, factory.longType), + "getFloat"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.floatType, factory.objectType, factory.longType), + "getFloat"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.intType, factory.longType), + "getInt"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.intType, factory.objectType, factory.longType), + "getInt"), + always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.getIntVolatile, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.longType, factory.longType), + "getLong"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.longType, factory.objectType, factory.longType), + "getLong"), + always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.getLongVolatile, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.objectType, factory.objectType, factory.longType), + "getObject"), + always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.getObjectVolatile, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.shortType, factory.longType), + "getShort"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.shortType, factory.objectType, factory.longType), + "getShort"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, factory.createProto(factory.sunMiscUnsafeType), "getUnsafe"), + always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, factory.createProto(factory.voidType), "loadFence"), + AndroidApiLevel.N); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.objectFieldOffset, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, factory.createProto(factory.intType), "pageSize"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.booleanType, factory.longType), + "park"), + always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.booleanType), + "putBoolean"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType, factory.byteType), + "putByte"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.byteType), + "putByte"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType, factory.charType), + "putChar"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.charType), + "putChar"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType, factory.doubleType), + "putDouble"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.doubleType), + "putDouble"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType, factory.floatType), + "putFloat"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.floatType), + "putFloat"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType, factory.intType), + "putInt"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.intType), + "putInt"), + always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.putIntVolatile, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType, factory.longType), + "putLong"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.longType), + "putLong"), + always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.putLongVolatile, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.objectType), + "putObject"), + always); + apiLevelConsumer.accept(factory.sunMiscUnsafeMethods.putObjectVolatile, always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.intType), + "putOrderedInt"), + always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.longType), + "putOrderedLong"), + always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.objectType), + "putOrderedObject"), + always); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.longType, factory.shortType), + "putShort"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.objectType, factory.longType, factory.shortType), + "putShort"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto( + factory.voidType, factory.longType, factory.longType, factory.byteType), + "setMemory"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, factory.createProto(factory.voidType), "storeFence"), + AndroidApiLevel.N); + apiLevelConsumer.accept( + factory.createMethod( + factory.sunMiscUnsafeType, + factory.createProto(factory.voidType, factory.objectType), + "unpark"), + always); + } +}
diff --git a/src/test/java/com/android/tools/r8/androidapi/SunMiscUnsafeApiTest.java b/src/test/java/com/android/tools/r8/androidapi/SunMiscUnsafeApiTest.java index 25dd428..1fa7679 100644 --- a/src/test/java/com/android/tools/r8/androidapi/SunMiscUnsafeApiTest.java +++ b/src/test/java/com/android/tools/r8/androidapi/SunMiscUnsafeApiTest.java
@@ -89,7 +89,7 @@ Map<ClassReference, AndroidApiLevel> classApis, Map<FieldReference, AndroidApiLevel> fieldApis, Map<MethodReference, AndroidApiLevel> methodApis) { - AndroidApiLevelDatabaseHelper.addUnsafeMethods( + AndroidApiLevelDatabaseTestHelper.addUnsafeMethods( // A short-lived item factory only used to extract non-canonical Reference-types. new DexItemFactory(), (reference, apiLevel) -> {
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java index dd1aafc..716a80a 100644 --- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java +++ b/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java
@@ -5,9 +5,9 @@ package com.android.tools.r8.apimodel; import static com.android.tools.r8.UnorderedCollectionMatcher.matchesItemsOneToOne; -import static com.android.tools.r8.androidapi.AndroidApiLevelDatabaseHelper.notModeledFields; -import static com.android.tools.r8.androidapi.AndroidApiLevelDatabaseHelper.notModeledMethods; import static com.android.tools.r8.androidapi.AndroidApiLevelDatabaseHelper.notModeledTypes; +import static com.android.tools.r8.androidapi.AndroidApiLevelDatabaseTestHelper.notModeledFields; +import static com.android.tools.r8.androidapi.AndroidApiLevelDatabaseTestHelper.notModeledMethods; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; @@ -21,6 +21,7 @@ import com.android.tools.r8.ToolHelper; import com.android.tools.r8.androidapi.AndroidApiLevelCompute; import com.android.tools.r8.androidapi.AndroidApiLevelCompute.DefaultAndroidApiLevelCompute; +import com.android.tools.r8.androidapi.AndroidApiLevelDatabaseTestHelper; import com.android.tools.r8.androidapi.AndroidApiLevelHashingDatabaseImpl; import com.android.tools.r8.androidapi.ApiDatabaseEntry; import com.android.tools.r8.androidapi.ComputedApiLevel; @@ -100,25 +101,34 @@ } } - private static GenerateDatabaseResourceFilesResult generateResourcesFiles() throws Exception { - Path androidJar = ToolHelper.getAndroidJar(API_LEVEL); - return generateResourcesFiles( - AndroidApiVersionsXmlParserChecked.parse( - ToolHelper.getApiVersionsXmlFile(API_LEVEL), androidJar, API_LEVEL, false), - API_LEVEL); + private static GenerateDatabaseResourceFilesResult generateResourcesFiles( + Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries) throws Exception { + TemporaryFolder temp1 = new TemporaryFolder(); + temp1.create(); + Path apiLevels = temp1.newFile("api_levels.ser").toPath(); + AndroidApiHashingDatabaseBuilderGenerator.writeEntries(databaseEntries, apiLevels); + return new GenerateDatabaseResourceFilesResult(apiLevels); } - private static GenerateDatabaseResourceFilesResult generateResourcesFiles( - List<ParsedApiClass> apiClasses, AndroidApiLevel androidJarApiLevel) throws Exception { - TemporaryFolder temp = new TemporaryFolder(); - temp.create(); - Path apiLevels = temp.newFile("api_levels.ser").toPath(); + private static Map<ApiDatabaseEntry, AndroidApiLevel> loadDatabaseEntries() throws Exception { + Path androidJar = ToolHelper.getAndroidJar(API_LEVEL); + List<ParsedApiClass> apiClasses = + AndroidApiVersionsXmlParserChecked.parse( + ToolHelper.getApiVersionsXmlFile(API_LEVEL), androidJar, API_LEVEL, false); DexItemFactory factory = new DexItemFactory(); - mergeCovariantMethods(apiClasses, factory); - + addCovariantMethods(apiClasses, factory); + addAdditionalKnownApiReferences(apiClasses, factory); Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries = AndroidApiHashingDatabaseBuilderGenerator.generateEntries(apiClasses); + verifyAgainstJar(apiClasses, databaseEntries, API_LEVEL); + return databaseEntries; + } + private static void verifyAgainstJar( + List<ParsedApiClass> apiClasses, + Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries, + AndroidApiLevel androidJarApiLevel) + throws Exception { Path androidJar = ToolHelper.getAndroidJar(androidJarApiLevel); AndroidApp androidApp = AndroidApp.builder() @@ -130,10 +140,6 @@ ensureAllPublicMethodsAreMapped( appView, apiClasses, databaseEntries, androidJarApiLevel, androidJar); - - AndroidApiHashingDatabaseBuilderGenerator.writeEntries(databaseEntries, apiLevels); - - return new GenerateDatabaseResourceFilesResult(apiLevels); } private static void ensureAllPublicMethodsAreMapped( @@ -196,28 +202,6 @@ } Set<DexType> expectedMissingMembers = new HashSet<>(); - // api-versions.xml do not encode all members of StringBuffers and StringBuilders, check that we - // only have missing definitions for those two classes. - expectedMissingMembers.add(factory.stringBufferType); - expectedMissingMembers.add(factory.stringBuilderType); - // TODO(b/231126636): api-versions.xml has missing definitions for the below classes. - expectedMissingMembers.add( - factory.createType("Ljava/util/concurrent/ConcurrentHashMap$KeySetView;")); - expectedMissingMembers.add(factory.createType("Ljava/time/chrono/ThaiBuddhistDate;")); - expectedMissingMembers.add(factory.createType("Ljava/time/chrono/HijrahDate;")); - expectedMissingMembers.add(factory.createType("Ljava/time/chrono/JapaneseDate;")); - expectedMissingMembers.add(factory.createType("Ljava/time/chrono/MinguoDate;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcV;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/IsoDep;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/MifareUltralight;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/MifareClassic;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NdefFormatable;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcA;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcBarcode;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcF;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcB;")); - expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/Ndef;")); - expectedMissingMembers.add(factory.createType("Landroid/webkit/CookieSyncManager;")); if (apiLevel.isLessThan(AndroidApiLevel.BAKLAVA_1)) { expectedMissingMembers.add( factory.createType("Landroid/adservices/adselection/AdSelectionOutcome;")); @@ -251,7 +235,7 @@ assertThat(missingMemberInformation.keySet(), matchesItemsOneToOne(expectedMissingMembers)); } - private static void mergeCovariantMethods(List<ParsedApiClass> apiClasses, DexItemFactory factory) + private static void addCovariantMethods(List<ParsedApiClass> apiClasses, DexItemFactory factory) throws Exception { CovariantMethodsInJarResult covariantMethodsInJar = CovariantMethodsInJarResult.create(); for (ParsedApiClass apiClass : apiClasses) { @@ -273,8 +257,48 @@ } } + private static void addAdditionalKnownApiReferences( + List<ParsedApiClass> apiClasses, DexItemFactory factory) { + Map<ClassReference, ParsedApiClass> lookupMap = new HashMap<>(); + for (ParsedApiClass apiClass : apiClasses) { + lookupMap.put(apiClass.getClassReference(), apiClass); + } + AndroidApiLevelDatabaseTestHelper.visitAdditionalKnownApiReferences( + factory, + (reference, apiLevel) -> { + if (reference.isDexType()) { + ClassReference classRef = reference.asDexType().asClassReference(); + assert !lookupMap.containsKey(classRef) : classRef + " is already registered"; + ParsedApiClass apiClass = new ParsedApiClass(classRef, apiLevel); + lookupMap.put(classRef, apiClass); + apiClasses.add(apiClass); + } else if (reference.isDexMethod()) { + MethodReference methodRef = reference.asDexMethod().asMethodReference(); + ClassReference holderRef = methodRef.getHolderClass(); + ParsedApiClass apiClass = lookupMap.get(holderRef); + if (apiClass == null) { + apiClass = new ParsedApiClass(holderRef, apiLevel); + lookupMap.put(holderRef, apiClass); + apiClasses.add(apiClass); + } + apiClass.registerMethod(methodRef, apiLevel); + } else if (reference.isDexField()) { + ClassReference holderRef = reference.asDexField().getHolderType().asClassReference(); + FieldTypelessReference fieldRef = + new FieldTypelessReference(holderRef, reference.asDexField().getName().toString()); + ParsedApiClass apiClass = lookupMap.get(holderRef); + if (apiClass == null) { + apiClass = new ParsedApiClass(holderRef, apiLevel); + lookupMap.put(holderRef, apiClass); + apiClasses.add(apiClass); + } + apiClass.registerField(fieldRef, apiLevel); + } + }); + } + @Test - public void testCanParseApiVersionsXml() throws Exception { + public void testParsedApiVersionsXmlSize() throws Exception { // This tests makes a rudimentary check on the number of classes, fields and methods in // api-versions.xml to ensure that the runtime tests do not vacuously succeed. List<ParsedApiClass> parsedApiClasses = @@ -291,9 +315,15 @@ numberOfMethods.increment(apiClass.methodCount()); }); // These numbers will change when updating api-versions.xml. - assertEquals(6498, parsedApiClasses.size()); - assertEquals(32818, numberOfFields.get()); - assertEquals(49867, numberOfMethods.get()); + assertEquals(6_498, parsedApiClasses.size()); + assertEquals(32_818, numberOfFields.get()); + assertEquals(49_867, numberOfMethods.get()); + } + + @Test + public void testEntrySize() throws Exception { + Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries = loadDatabaseEntries(); + assertEquals(252_214, databaseEntries.size()); } private static final String sampleVersion4ApiVersionsXml = @@ -337,7 +367,8 @@ + " </class>\n" + "</api>\n"; - static class SdkExtensions { + static class SdkExtensionsStub { + @SuppressWarnings("unused") int AD_SERVICES; } @@ -349,7 +380,7 @@ ZipUtils.writeToZipStream( out, "android/os/ext/SdkExtensions.class", - transformer(SdkExtensions.class) + transformer(SdkExtensionsStub.class) .setClassDescriptor("Landroid/os/ext/SdkExtensions;") .transform(), ZipEntry.STORED); @@ -444,7 +475,7 @@ @Test public void testDatabaseGenerationUpToDate() throws Exception { - GenerateDatabaseResourceFilesResult result = generateResourcesFiles(); + GenerateDatabaseResourceFilesResult result = generateResourcesFiles(loadDatabaseEntries()); assertTrue(TestBase.filesAreEqual(result.apiLevels, API_DATABASE)); } @@ -745,7 +776,7 @@ * third_party/api_database/api_database.ser. */ public static void main(String[] args) throws Exception { - GenerateDatabaseResourceFilesResult result = generateResourcesFiles(); + GenerateDatabaseResourceFilesResult result = generateResourcesFiles(loadDatabaseEntries()); API_DATABASE.toFile().mkdirs(); Files.move(result.apiLevels, API_DATABASE, REPLACE_EXISTING); System.out.println(
diff --git a/third_party/api_database/api_database.tar.gz.sha1 b/third_party/api_database/api_database.tar.gz.sha1 index 2e42cfa..4ecd278 100644 --- a/third_party/api_database/api_database.tar.gz.sha1 +++ b/third_party/api_database/api_database.tar.gz.sha1
@@ -1 +1 @@ -dd6a83d38c6885c1f0c41f4b177a1f7c3681d948 \ No newline at end of file +908f6a2e1b60270e5e6d74f9304436fe3a5d8b85 \ No newline at end of file