Add support for reading the new hidden api restrictions in dexlib2

This commit is contained in:
Ben Gruver 2020-02-01 14:30:15 -08:00
parent 1590b4a05e
commit 36c94ad653
31 changed files with 613 additions and 35 deletions

View File

@ -38,6 +38,7 @@ import org.jf.baksmali.Adaptors.Format.InstructionMethodItem;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.dexlib2.Format;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.base.reference.BaseMethodReference;
@ -199,6 +200,10 @@ public class InstructionMethodItemTest {
public String getReturnType() {
return "V";
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return ImmutableSet.of();
}
}
private static class TestClassDef extends BaseTypeReference implements ClassDef {

View File

@ -0,0 +1,110 @@
/*
* Copyright 2020, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import java.util.StringJoiner;
public enum HiddenApiRestriction {
WHITELIST(0, "whitelist", false),
GREYLIST(1, "greylist", false),
BLACKLIST(2, "blacklist", false),
GREYLIST_MAX_O(3, "greylist-max-o", false),
GREYLIST_MAX_P(4, "greylist-max-p", false),
GREYLIST_MAX_Q(5, "greylist-max-q", false),
CORE_PLATFORM_API(8, "core-platform-api", true);
private static final HiddenApiRestriction[] hiddenApiFlags = new HiddenApiRestriction[] {
WHITELIST,
GREYLIST,
BLACKLIST,
GREYLIST_MAX_O,
GREYLIST_MAX_P,
GREYLIST_MAX_Q
};
private static final HiddenApiRestriction[] domainSpecificApiFlags = new HiddenApiRestriction[] {
CORE_PLATFORM_API
};
private static final int HIDDENAPI_FLAG_MASK = 0x7;
private final int value;
private final String name;
private final boolean isDomainSpecificApiFlag;
HiddenApiRestriction(int value, String name, boolean isDomainSpecificApiFlag) {
this.value = value;
this.name = name;
this.isDomainSpecificApiFlag = isDomainSpecificApiFlag;
}
public String toString() {
return name;
}
public int getValue() {
return value;
}
public boolean isSet(int value) {
if (isDomainSpecificApiFlag) {
return (value & ~HIDDENAPI_FLAG_MASK) == this.value;
} else {
return (value & HIDDENAPI_FLAG_MASK) == this.value;
}
}
public boolean isDomainSpecificApiFlag() {
return isDomainSpecificApiFlag;
}
public static Set<HiddenApiRestriction> getAllFlags(int value) {
HiddenApiRestriction normalRestriction = hiddenApiFlags[value & HIDDENAPI_FLAG_MASK];
int domainSpecificPart = (value & ~HIDDENAPI_FLAG_MASK);
if (domainSpecificPart == 0) {
return ImmutableSet.of(normalRestriction);
}
return ImmutableSet.of(normalRestriction, domainSpecificApiFlags[(domainSpecificPart >> 3) - 1]);
}
public static String formatHiddenRestrictions(int value) {
StringJoiner joiner = new StringJoiner("|");
for (HiddenApiRestriction hiddenApiRestriction : getAllFlags(value)) {
joiner.add(hiddenApiRestriction.toString());
}
return joiner.toString();
}
}

View File

@ -38,13 +38,14 @@ import com.google.common.base.Suppliers;
import com.google.common.collect.*;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.analysis.util.TypeProtoUtils;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.*;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.util.MethodUtil;
import org.jf.dexlib2.util.AlignmentUtils;
import org.jf.dexlib2.util.MethodUtil;
import org.jf.util.ExceptionWithContext;
import org.jf.util.SparseArray;
@ -1285,6 +1286,10 @@ public class ClassProto implements TypeProto {
return method.getAnnotations();
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return method.getHiddenApiRestrictions();
}
@Nullable @Override public MethodImplementation getImplementation() {
return method.getImplementation();
}

View File

@ -133,6 +133,6 @@ public class CustomInlineMethodResolver extends InlineMethodResolver {
throw new RuntimeException("Cannot resolve inline method: " + inlineMethod);
}
return new ImmutableMethod(className, methodName, methodParams, methodRet, accessFlags, null, null);
return new ImmutableMethod(className, methodName, methodParams, methodRet, accessFlags, null, null, null);
}
}

View File

@ -67,7 +67,7 @@ public abstract class InlineMethodResolver {
private static Method inlineMethod(int accessFlags, @Nonnull String cls, @Nonnull String name,
@Nonnull String params, @Nonnull String returnType) {
ImmutableList<ImmutableMethodParameter> paramList = ImmutableList.copyOf(ParamUtil.parseParamString(params));
return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null);
return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null, null);
}
@Nonnull public abstract Method resolveExecuteInline(@Nonnull AnalyzedInstruction instruction);

View File

@ -32,6 +32,7 @@
package org.jf.dexlib2.analysis.reflection;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.analysis.reflection.util.ReflectionUtils;
import org.jf.dexlib2.base.BaseMethodParameter;
import org.jf.dexlib2.base.reference.BaseMethodReference;
@ -118,4 +119,8 @@ public class ReflectionConstructor extends BaseMethodReference implements Method
@Nonnull @Override public String getReturnType() {
return "V";
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return ImmutableSet.of();
}
}

View File

@ -32,6 +32,7 @@
package org.jf.dexlib2.analysis.reflection;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.analysis.reflection.util.ReflectionUtils;
import org.jf.dexlib2.base.reference.BaseFieldReference;
import org.jf.dexlib2.iface.Annotation;
@ -72,4 +73,8 @@ public class ReflectionField extends BaseFieldReference implements Field {
@Nonnull @Override public String getType() {
return ReflectionUtils.javaToDexName(field.getType().getName());
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return ImmutableSet.of();
}
}

View File

@ -32,6 +32,7 @@
package org.jf.dexlib2.analysis.reflection;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.analysis.reflection.util.ReflectionUtils;
import org.jf.dexlib2.base.BaseMethodParameter;
import org.jf.dexlib2.base.reference.BaseMethodReference;
@ -117,4 +118,8 @@ public class ReflectionMethod extends BaseMethodReference implements Method {
@Nonnull @Override public String getReturnType() {
return ReflectionUtils.javaToDexName(method.getReturnType().getName());
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return ImmutableSet.of();
}
}

View File

@ -39,6 +39,7 @@ import org.jf.dexlib2.dexbacked.raw.ClassDefItem;
import org.jf.dexlib2.dexbacked.raw.TypeIdItem;
import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
import org.jf.dexlib2.dexbacked.util.EncodedArrayItemIterator;
import org.jf.dexlib2.dexbacked.util.VariableSizeListIterator;
import org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.reference.FieldReference;
@ -53,9 +54,14 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static org.jf.dexlib2.writer.DexWriter.NO_OFFSET;
public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
static final int NO_HIDDEN_API_RESTRICTIONS = 7;
@Nonnull public final DexBackedDexFile dexFile;
private final int classDefOffset;
@Nullable private final HiddenApiRestrictionsReader hiddenApiRestrictionsReader;
private final int staticFieldsOffset;
private int instanceFieldsOffset = 0;
@ -70,7 +76,8 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
@Nullable private AnnotationsDirectory annotationsDirectory;
public DexBackedClassDef(@Nonnull DexBackedDexFile dexFile,
int classDefOffset) {
int classDefOffset,
int hiddenApiRestrictionsOffset) {
this.dexFile = dexFile;
this.classDefOffset = classDefOffset;
@ -90,6 +97,11 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
staticFieldsOffset = reader.getOffset();
}
if (hiddenApiRestrictionsOffset != NO_OFFSET) {
hiddenApiRestrictionsReader = new HiddenApiRestrictionsReader(hiddenApiRestrictionsOffset);
} else {
hiddenApiRestrictionsReader = null;
}
}
@Nonnull
@ -154,13 +166,17 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
@Nonnull
public Iterable<? extends DexBackedField> getStaticFields(final boolean skipDuplicates) {
if (staticFieldCount > 0) {
DexReader reader = dexFile.getDataBuffer().readerAt(staticFieldsOffset);
DexReader<? extends DexBuffer> reader = dexFile.getDataBuffer().readerAt(staticFieldsOffset);
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final int staticInitialValuesOffset =
dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
final int fieldsStartOffset = reader.getOffset();
Iterator<Integer> hiddenApiRestrictionIterator = hiddenApiRestrictionsReader == null ?
null : hiddenApiRestrictionsReader.getRestrictionsForStaticFields();
return new Iterable<DexBackedField>() {
@Nonnull
@Override
@ -185,8 +201,14 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
return endOfData();
}
int hiddenApiRestrictions = NO_HIDDEN_API_RESTRICTIONS;
if (hiddenApiRestrictionIterator != null) {
hiddenApiRestrictions = hiddenApiRestrictionIterator.next();
}
DexBackedField item = new DexBackedField(dexFile, reader, DexBackedClassDef.this,
previousIndex, staticInitialValueIterator, annotationIterator);
previousIndex, staticInitialValueIterator, annotationIterator,
hiddenApiRestrictions);
FieldReference currentField = previousField;
FieldReference nextField = ImmutableFieldReference.of(item);
@ -223,6 +245,9 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final int fieldsStartOffset = reader.getOffset();
Iterator<Integer> hiddenApiRestrictionIterator = hiddenApiRestrictionsReader == null ?
null : hiddenApiRestrictionsReader.getRestrictionsForInstanceFields();
return new Iterable<DexBackedField>() {
@Nonnull
@Override
@ -245,8 +270,13 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
return endOfData();
}
int hiddenApiRestrictions = NO_HIDDEN_API_RESTRICTIONS;
if (hiddenApiRestrictionIterator != null) {
hiddenApiRestrictions = hiddenApiRestrictionIterator.next();
}
DexBackedField item = new DexBackedField(dexFile, reader, DexBackedClassDef.this,
previousIndex, annotationIterator);
previousIndex, annotationIterator, hiddenApiRestrictions);
FieldReference currentField = previousField;
FieldReference nextField = ImmutableFieldReference.of(item);
@ -291,6 +321,9 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final int methodsStartOffset = reader.getOffset();
Iterator<Integer> hiddenApiRestrictionIterator = hiddenApiRestrictionsReader == null ?
null : hiddenApiRestrictionsReader.getRestrictionsForDirectMethods();
return new Iterable<DexBackedMethod>() {
@Nonnull
@Override
@ -315,8 +348,14 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
return endOfData();
}
int hiddenApiRestrictions = NO_HIDDEN_API_RESTRICTIONS;
if (hiddenApiRestrictionIterator != null) {
hiddenApiRestrictions = hiddenApiRestrictionIterator.next();
}
DexBackedMethod item = new DexBackedMethod(dexFile, reader, DexBackedClassDef.this,
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
previousIndex, methodAnnotationIterator, parameterAnnotationIterator,
hiddenApiRestrictions);
MethodReference currentMethod = previousMethod;
MethodReference nextMethod = ImmutableMethodReference.of(item);
@ -349,6 +388,9 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final int methodsStartOffset = reader.getOffset();
Iterator<Integer> hiddenApiRestrictionIterator = hiddenApiRestrictionsReader == null ?
null : hiddenApiRestrictionsReader.getRestrictionsForVirtualMethods();
return new Iterable<DexBackedMethod>() {
final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator =
annotationsDirectory.getMethodAnnotationIterator();
@ -372,8 +414,14 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
return endOfData();
}
int hiddenApiRestrictions = NO_HIDDEN_API_RESTRICTIONS;
if (hiddenApiRestrictionIterator != null) {
hiddenApiRestrictions = hiddenApiRestrictionIterator.next();
}
DexBackedMethod item = new DexBackedMethod(dexFile, reader, DexBackedClassDef.this,
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
previousIndex, methodAnnotationIterator, parameterAnnotationIterator,
hiddenApiRestrictions);
MethodReference currentMethod = previousMethod;
MethodReference nextMethod = ImmutableMethodReference.of(item);
@ -506,4 +554,110 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
}
return size;
}
private class HiddenApiRestrictionsReader {
private final int startOffset;
private int instanceFieldsStartOffset;
private int directMethodsStartOffset;
private int virtualMethodsStartOffset;
public HiddenApiRestrictionsReader(int startOffset) {
this.startOffset = startOffset;
}
private VariableSizeListIterator<Integer> getRestrictionsForStaticFields() {
return new VariableSizeListIterator<Integer>(
dexFile.getDataBuffer(), startOffset, staticFieldCount) {
@Override protected Integer readNextItem(
@Nonnull DexReader<? extends DexBuffer> reader, int index) {
return reader.readSmallUleb128();
}
@Override public Integer next() {
if (nextIndex() == staticFieldCount) {
instanceFieldsStartOffset = getReaderOffset();
}
return super.next();
}
};
}
private int getInstanceFieldsStartOffset() {
if (instanceFieldsStartOffset == NO_OFFSET) {
DexReader<? extends DexBuffer> reader = dexFile.getDataBuffer().readerAt(startOffset);
for (int i = 0; i < staticFieldCount; i++) {
reader.readSmallUleb128();
}
instanceFieldsStartOffset = reader.getOffset();
}
return instanceFieldsStartOffset;
}
private Iterator<Integer> getRestrictionsForInstanceFields() {
return new VariableSizeListIterator<Integer>(
dexFile.getDataBuffer(), getInstanceFieldsStartOffset(), instanceFieldCount) {
@Override protected Integer readNextItem(
@Nonnull DexReader<? extends DexBuffer> reader, int index) {
return reader.readSmallUleb128();
}
@Override public Integer next() {
if (nextIndex() == instanceFieldCount) {
directMethodsStartOffset = getReaderOffset();
}
return super.next();
}
};
}
private int getDirectMethodsStartOffset() {
if (directMethodsStartOffset == NO_OFFSET) {
DexReader<? extends DexBuffer> reader = dexFile.getDataBuffer().readerAt(getInstanceFieldsStartOffset());
for (int i = 0; i < instanceFieldCount; i++) {
reader.readSmallUleb128();
}
directMethodsStartOffset = reader.getOffset();
}
return directMethodsStartOffset;
}
private Iterator<Integer> getRestrictionsForDirectMethods() {
return new VariableSizeListIterator<Integer>(
dexFile.getDataBuffer(), getDirectMethodsStartOffset(), directMethodCount) {
@Override protected Integer readNextItem(
@Nonnull DexReader<? extends DexBuffer> reader, int index) {
return reader.readSmallUleb128();
}
@Override public Integer next() {
if (nextIndex() == directMethodCount) {
virtualMethodsStartOffset = getReaderOffset();
}
return super.next();
}
};
}
private int getVirtualMethodsStartOffset() {
if (virtualMethodsStartOffset == NO_OFFSET) {
DexReader<? extends DexBuffer> reader = dexFile.getDataBuffer().readerAt(getDirectMethodsStartOffset());
for (int i = 0; i < directMethodCount; i++) {
reader.readSmallUleb128();
}
virtualMethodsStartOffset = reader.getOffset();
}
return virtualMethodsStartOffset;
}
private Iterator<Integer> getRestrictionsForVirtualMethods() {
return new VariableSizeListIterator<Integer>(
dexFile.getDataBuffer(), getVirtualMethodsStartOffset(), virtualMethodCount) {
@Override protected Integer readNextItem(
@Nonnull DexReader<? extends DexBuffer> reader, int index) {
return reader.readSmallUleb128();
}
};
}
}
}

View File

@ -50,6 +50,8 @@ import java.util.AbstractList;
import java.util.List;
import java.util.Set;
import static org.jf.dexlib2.writer.DexWriter.NO_OFFSET;
public class DexBackedDexFile implements DexFile {
private final DexBuffer dexBuffer;
@ -70,6 +72,7 @@ public class DexBackedDexFile implements DexFile {
private final int classCount;
private final int classStartOffset;
private final int mapOffset;
private final int hiddenApiRestrictionsOffset;
protected DexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) {
dexBuffer = new DexBuffer(buf, offset);
@ -125,6 +128,13 @@ public class DexBackedDexFile implements DexFile {
classCount = dexBuffer.readSmallUint(HeaderItem.CLASS_COUNT_OFFSET);
classStartOffset = dexBuffer.readSmallUint(HeaderItem.CLASS_START_OFFSET);
mapOffset = dexBuffer.readSmallUint(HeaderItem.MAP_OFFSET);
MapItem mapItem = getMapItemForSection(ItemType.HIDDENAPI_CLASS_DATA_ITEM);
if (mapItem != null) {
hiddenApiRestrictionsOffset = mapItem.getOffset();
} else {
hiddenApiRestrictionsOffset = NO_OFFSET;
}
}
/**
@ -444,7 +454,8 @@ public class DexBackedDexFile implements DexFile {
private IndexedSection<DexBackedClassDef> classSection = new IndexedSection<DexBackedClassDef>() {
@Override
public DexBackedClassDef get(int index) {
return new DexBackedClassDef(DexBackedDexFile.this, getOffset(index));
return new DexBackedClassDef(DexBackedDexFile.this, getOffset(index),
readHiddenApiRestrictionsOffset(index));
}
@Override
@ -534,6 +545,22 @@ public class DexBackedDexFile implements DexFile {
return new DexBackedMethodImplementation(dexFile, method, codeOffset);
}
private int readHiddenApiRestrictionsOffset(int classIndex) {
if (hiddenApiRestrictionsOffset == NO_OFFSET) {
return NO_OFFSET;
}
int offset = dexBuffer.readInt(
hiddenApiRestrictionsOffset +
HiddenApiClassDataItem.OFFSETS_LIST_OFFSET +
classIndex * HiddenApiClassDataItem.OFFSET_ITEM_SIZE);
if (offset == NO_OFFSET) {
return NO_OFFSET;
}
return hiddenApiRestrictionsOffset + offset;
}
public static abstract class OptionalIndexedSection<T> extends IndexedSection<T> {
/**
* @param index The index of the item, or -1 for a null item.

View File

@ -31,6 +31,8 @@
package org.jf.dexlib2.dexbacked;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseFieldReference;
import org.jf.dexlib2.dexbacked.raw.FieldIdItem;
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference;
@ -43,6 +45,7 @@ import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Set;
public class DexBackedField extends BaseFieldReference implements Field {
@ -56,6 +59,7 @@ public class DexBackedField extends BaseFieldReference implements Field {
public final int fieldIndex;
private final int startOffset;
private final int initialValueOffset;
private final int hiddenApiRestrictions;
private int fieldIdItemOffset;
@ -64,7 +68,8 @@ public class DexBackedField extends BaseFieldReference implements Field {
@Nonnull DexBackedClassDef classDef,
int previousFieldIndex,
@Nonnull EncodedArrayItemIterator staticInitialValueIterator,
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator,
int hiddenApiRestrictions) {
this.dexFile = dexFile;
this.classDef = classDef;
@ -78,13 +83,15 @@ public class DexBackedField extends BaseFieldReference implements Field {
this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
initialValueOffset = staticInitialValueIterator.getReaderOffset();
this.initialValue = staticInitialValueIterator.getNextOrNull();
this.hiddenApiRestrictions = hiddenApiRestrictions;
}
public DexBackedField(@Nonnull DexBackedDexFile dexFile,
@Nonnull DexReader reader,
@Nonnull DexBackedClassDef classDef,
int previousFieldIndex,
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator,
int hiddenApiRestrictions) {
this.dexFile = dexFile;
this.classDef = classDef;
@ -98,6 +105,7 @@ public class DexBackedField extends BaseFieldReference implements Field {
this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
initialValueOffset = 0;
this.initialValue = null;
this.hiddenApiRestrictions = hiddenApiRestrictions;
}
@Nonnull
@ -124,6 +132,16 @@ public class DexBackedField extends BaseFieldReference implements Field {
return AnnotationsDirectory.getAnnotations(dexFile, annotationSetOffset);
}
@Nonnull
@Override
public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
if (hiddenApiRestrictions == DexBackedClassDef.NO_HIDDEN_API_RESTRICTIONS) {
return ImmutableSet.of();
} else {
return EnumSet.copyOf(HiddenApiRestriction.getAllFlags(hiddenApiRestrictions));
}
}
/**
* Skips the reader over the specified number of encoded_field structures
*

View File

@ -33,6 +33,7 @@ package org.jf.dexlib2.dexbacked;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.dexbacked.raw.MethodIdItem;
import org.jf.dexlib2.dexbacked.raw.ProtoIdItem;
@ -48,6 +49,7 @@ import org.jf.util.AbstractForwardSequentialList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@ -61,6 +63,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
private final int codeOffset;
private final int parameterAnnotationSetListOffset;
private final int methodAnnotationSetOffset;
private final int hiddenApiRestrictions;
public final int methodIndex;
private final int startOffset;
@ -72,7 +75,8 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
public DexBackedMethod(@Nonnull DexBackedDexFile dexFile,
@Nonnull DexReader reader,
@Nonnull DexBackedClassDef classDef,
int previousMethodIndex) {
int previousMethodIndex,
int hiddenApiRestrictions) {
this.dexFile = dexFile;
this.classDef = classDef;
startOffset = reader.getOffset();
@ -83,6 +87,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
this.methodIndex = methodIndexDiff + previousMethodIndex;
this.accessFlags = reader.readSmallUleb128();
this.codeOffset = reader.readSmallUleb128();
this.hiddenApiRestrictions = hiddenApiRestrictions;
this.methodAnnotationSetOffset = 0;
this.parameterAnnotationSetListOffset = 0;
@ -93,7 +98,8 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
@Nonnull DexBackedClassDef classDef,
int previousMethodIndex,
@Nonnull AnnotationsDirectory.AnnotationIterator methodAnnotationIterator,
@Nonnull AnnotationsDirectory.AnnotationIterator paramaterAnnotationIterator) {
@Nonnull AnnotationsDirectory.AnnotationIterator paramaterAnnotationIterator,
int hiddenApiRestrictions) {
this.dexFile = dexFile;
this.classDef = classDef;
startOffset = reader.getOffset();
@ -104,6 +110,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
this.methodIndex = methodIndexDiff + previousMethodIndex;
this.accessFlags = reader.readSmallUleb128();
this.codeOffset = reader.readSmallUleb128();
this.hiddenApiRestrictions = hiddenApiRestrictions;
this.methodAnnotationSetOffset = methodAnnotationIterator.seekTo(methodIndex);
this.parameterAnnotationSetListOffset = paramaterAnnotationIterator.seekTo(methodIndex);
@ -188,6 +195,16 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
return AnnotationsDirectory.getAnnotations(dexFile, methodAnnotationSetOffset);
}
@Nonnull
@Override
public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
if (hiddenApiRestrictions == DexBackedClassDef.NO_HIDDEN_API_RESTRICTIONS) {
return ImmutableSet.of();
} else {
return EnumSet.copyOf(HiddenApiRestriction.getAllFlags(hiddenApiRestrictions));
}
}
@Nullable
@Override
public DexBackedMethodImplementation getImplementation() {

View File

@ -141,7 +141,7 @@ public class DexBuffer {
}
@Nonnull
public DexReader readerAt(int offset) {
public DexReader<? extends DexBuffer> readerAt(int offset) {
return new DexReader<DexBuffer>(this, offset);
}

View File

@ -0,0 +1,136 @@
/*
* Copyright 2013, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.dexbacked.raw;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.Field;
import org.jf.dexlib2.iface.Method;
import org.jf.dexlib2.util.AnnotatedBytes;
import org.jf.dexlib2.util.ReferenceUtil;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class HiddenApiClassDataItem {
public static final int SIZE_OFFSET = 0x0;
public static final int OFFSETS_LIST_OFFSET = 0x4;
public static final int OFFSET_ITEM_SIZE = 0x4;
@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
return new SectionAnnotator(annotator, mapItem) {
@Nonnull @Override public String getItemName() {
return "hiddenapi_class_data_item";
}
@Override
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
int startOffset = out.getCursor();
out.annotate(4, "size = 0x%x", dexFile.getDataBuffer().readSmallUint(out.getCursor()));
int index = 0;
for (ClassDef classDef : dexFile.getClasses()) {
out.annotate(0, "[%d] %s", index, ReferenceUtil.getReferenceString(classDef));
out.indent();
int offset = dexFile.getDataBuffer().readSmallUint(out.getCursor());
if (offset == 0) {
out.annotate(4, "offset = 0x%x", offset);
} else {
out.annotate(4, "offset = 0x%x (absolute offset: 0x%x)", offset, startOffset + offset);
}
int nextOffset = out.getCursor();
if (offset > 0) {
out.deindent();
out.moveTo(startOffset + offset);
DexReader<? extends DexBuffer> reader = dexFile.getBuffer().readerAt(out.getCursor());
for (Field field : classDef.getStaticFields()) {
out.annotate(0, "%s:", ReferenceUtil.getReferenceString(field));
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s",
restrictions,
HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
for (Field field : classDef.getInstanceFields()) {
out.annotate(0, "%s:", ReferenceUtil.getReferenceString(field));
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s",
restrictions,
HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
for (Method method : classDef.getDirectMethods()) {
out.annotate(0, "%s:", ReferenceUtil.getReferenceString(method));
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s",
restrictions,
HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
for (Method method : classDef.getVirtualMethods()) {
out.annotate(0, "%s:", ReferenceUtil.getReferenceString(method));
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s",
restrictions,
HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
out.indent();
}
out.moveTo(nextOffset);
out.deindent();
index++;
}
}
};
}
}

View File

@ -54,6 +54,7 @@ public class ItemType {
public static final int ANNOTATION_ITEM = 0x2004;
public static final int ENCODED_ARRAY_ITEM = 0x2005;
public static final int ANNOTATION_DIRECTORY_ITEM = 0x2006;
public static final int HIDDENAPI_CLASS_DATA_ITEM = 0xF000;
@Nonnull
public static String getItemTypeName(int itemType) {
@ -78,6 +79,7 @@ public class ItemType {
case ANNOTATION_ITEM: return "annotation_item";
case ENCODED_ARRAY_ITEM: return "encoded_array_item";
case ANNOTATION_DIRECTORY_ITEM: return "annotation_directory_item";
case HIDDENAPI_CLASS_DATA_ITEM: return "hiddenapi_class_data_item";
default: return "unknown dex item type";
}
}

View File

@ -78,7 +78,9 @@ public class DexAnnotator extends AnnotatedBytes {
ItemType.STRING_DATA_ITEM,
ItemType.ANNOTATION_ITEM,
ItemType.ENCODED_ARRAY_ITEM,
ItemType.ANNOTATION_DIRECTORY_ITEM
ItemType.ANNOTATION_DIRECTORY_ITEM,
ItemType.HIDDENAPI_CLASS_DATA_ITEM
};
for (int i=0; i<sectionOrder.length; i++) {
@ -153,6 +155,9 @@ public class DexAnnotator extends AnnotatedBytes {
case ItemType.METHOD_HANDLE_ITEM:
annotators.put(mapItem.getType(), MethodHandleItem.makeAnnotator(this, mapItem));
break;
case ItemType.HIDDENAPI_CLASS_DATA_ITEM:
annotators.put(mapItem.getType(), HiddenApiClassDataItem.makeAnnotator(this, mapItem));
break;
default:
throw new RuntimeException(String.format("Unrecognized item type: 0x%x", mapItem.getType()));
}

View File

@ -39,7 +39,7 @@ import java.util.ListIterator;
import java.util.NoSuchElementException;
public abstract class VariableSizeListIterator<T> implements ListIterator<T> {
@Nonnull private DexReader reader;
@Nonnull private DexReader<? extends DexBuffer> reader;
protected final int size;
private final int startOffset;
@ -58,7 +58,7 @@ public abstract class VariableSizeListIterator<T> implements ListIterator<T> {
* @param index The index of the item being read. This is guaranteed to be less than {@code size}
* @return The item that was read
*/
protected abstract T readNextItem(@Nonnull DexReader reader, int index);
protected abstract T readNextItem(@Nonnull DexReader<? extends DexBuffer> reader, int index);
public int getReaderOffset() {
return reader.getOffset();

View File

@ -31,6 +31,7 @@
package org.jf.dexlib2.iface;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.iface.value.EncodedValue;
@ -93,4 +94,14 @@ public interface Field extends FieldReference, Member {
* @return A set of the annotations that are applied to this field
*/
@Override @Nonnull Set<? extends Annotation> getAnnotations();
/**
* Gets the hidden api restrictions for this field.
*
* This will contain at most 1 normal flag (with isDomainSpecificApiFlag() = false), and 1
* domain-specific api flag (with isDomainSpecificApiFlag() = true)
*
* @return A set of the hidden api restrictions for this field.
*/
@Nonnull Set<HiddenApiRestriction> getHiddenApiRestrictions();
}

View File

@ -31,7 +31,10 @@
package org.jf.dexlib2.iface;
import org.jf.dexlib2.HiddenApiRestriction;
import javax.annotation.Nonnull;
import java.util.Set;
/**
* This class represents a generic class member
@ -60,4 +63,14 @@ public interface Member extends Annotatable {
* @return The access flags for this member
*/
int getAccessFlags();
/**
* Gets the hidden api restrictions for this member.
*
* This will contain at most 1 normal flag (with isDomainSpecificApiFlag() = false), and 1
* domain-specific api flag (with isDomainSpecificApiFlag() = true)
*
* @return A set of the hidden api restrictions for this member.
*/
@Nonnull Set<HiddenApiRestriction> getHiddenApiRestrictions();
}

View File

@ -31,6 +31,7 @@
package org.jf.dexlib2.iface;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.iface.reference.MethodReference;
import javax.annotation.Nonnull;
@ -97,6 +98,16 @@ public interface Method extends MethodReference, Member {
*/
@Override @Nonnull Set<? extends Annotation> getAnnotations();
/**
* Gets the hidden api restrictions for this method.
*
* This will contain at most 1 normal flag (with isDomainSpecificApiFlag() = false), and 1
* domain-specific api flag (with isDomainSpecificApiFlag() = true)
*
* @return A set of the hidden api restrictions for this method.
*/
@Nonnull Set<HiddenApiRestriction> getHiddenApiRestrictions();
/**
* Gets a MethodImplementation object that defines the implementation of the method.
*

View File

@ -34,6 +34,7 @@ package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseFieldReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Field;
@ -46,6 +47,7 @@ import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Set;
public class ImmutableField extends BaseFieldReference implements Field {
@Nonnull protected final String definingClass;
@ -54,19 +56,23 @@ public class ImmutableField extends BaseFieldReference implements Field {
protected final int accessFlags;
@Nullable protected final ImmutableEncodedValue initialValue;
@Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
@Nonnull protected final ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions;
public ImmutableField(@Nonnull String definingClass,
@Nonnull String name,
@Nonnull String type,
int accessFlags,
@Nullable EncodedValue initialValue,
@Nullable Collection<? extends Annotation> annotations) {
@Nullable Collection<? extends Annotation> annotations,
@Nullable Set<HiddenApiRestriction> hiddenApiRestrictions) {
this.definingClass = definingClass;
this.name = name;
this.type = type;
this.accessFlags = accessFlags;
this.initialValue = ImmutableEncodedValueFactory.ofNullable(initialValue);
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
this.hiddenApiRestrictions =
hiddenApiRestrictions == null ? ImmutableSet.of() : ImmutableSet.copyOf(hiddenApiRestrictions);
}
public ImmutableField(@Nonnull String definingClass,
@ -74,13 +80,15 @@ public class ImmutableField extends BaseFieldReference implements Field {
@Nonnull String type,
int accessFlags,
@Nullable ImmutableEncodedValue initialValue,
@Nullable ImmutableSet<? extends ImmutableAnnotation> annotations) {
@Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
@Nullable ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions) {
this.definingClass = definingClass;
this.name = name;
this.type = type;
this.accessFlags = accessFlags;
this.initialValue = initialValue;
this.annotations = ImmutableUtils.nullToEmptySet(annotations);
this.hiddenApiRestrictions = ImmutableUtils.nullToEmptySet(hiddenApiRestrictions);
}
public static ImmutableField of(Field field) {
@ -93,7 +101,8 @@ public class ImmutableField extends BaseFieldReference implements Field {
field.getType(),
field.getAccessFlags(),
field.getInitialValue(),
field.getAnnotations());
field.getAnnotations(),
field.getHiddenApiRestrictions());
}
@Nonnull @Override public String getDefiningClass() { return definingClass; }
@ -102,6 +111,7 @@ public class ImmutableField extends BaseFieldReference implements Field {
@Override public int getAccessFlags() { return accessFlags; }
@Override public EncodedValue getInitialValue() { return initialValue;}
@Nonnull @Override public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() { return hiddenApiRestrictions; }
@Nonnull
public static ImmutableSortedSet<ImmutableField> immutableSetOf(@Nullable Iterable<? extends Field> list) {

View File

@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Method;
@ -54,6 +55,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
@Nonnull protected final String returnType;
protected final int accessFlags;
@Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
@Nonnull protected final ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions;
@Nullable protected final ImmutableMethodImplementation methodImplementation;
public ImmutableMethod(@Nonnull String definingClass,
@ -62,6 +64,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
@Nonnull String returnType,
int accessFlags,
@Nullable Set<? extends Annotation> annotations,
@Nullable Set<HiddenApiRestriction> hiddenApiRestrictions,
@Nullable MethodImplementation methodImplementation) {
this.definingClass = definingClass;
this.name = name;
@ -69,6 +72,8 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
this.returnType = returnType;
this.accessFlags = accessFlags;
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
this.hiddenApiRestrictions =
hiddenApiRestrictions == null ? ImmutableSet.of() : ImmutableSet.copyOf(hiddenApiRestrictions);
this.methodImplementation = ImmutableMethodImplementation.of(methodImplementation);
}
@ -78,6 +83,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
@Nonnull String returnType,
int accessFlags,
@Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
@Nullable ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions,
@Nullable ImmutableMethodImplementation methodImplementation) {
this.definingClass = definingClass;
this.name = name;
@ -85,6 +91,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
this.returnType = returnType;
this.accessFlags = accessFlags;
this.annotations = ImmutableUtils.nullToEmptySet(annotations);
this.hiddenApiRestrictions = ImmutableUtils.nullToEmptySet(hiddenApiRestrictions);
this.methodImplementation = methodImplementation;
}
@ -99,6 +106,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
method.getReturnType(),
method.getAccessFlags(),
method.getAnnotations(),
method.getHiddenApiRestrictions(),
method.getImplementation());
}
@ -109,6 +117,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
@Override @Nonnull public String getReturnType() { return returnType; }
@Override public int getAccessFlags() { return accessFlags; }
@Override @Nonnull public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() { return hiddenApiRestrictions; }
@Override @Nullable public ImmutableMethodImplementation getImplementation() { return methodImplementation; }
@Nonnull

View File

@ -31,6 +31,7 @@
package org.jf.dexlib2.rewriter;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseFieldReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Field;
@ -81,5 +82,9 @@ public class FieldRewriter implements Rewriter<Field> {
@Nonnull public Set<? extends Annotation> getAnnotations() {
return RewriterUtils.rewriteSet(rewriters.getAnnotationRewriter(), field.getAnnotations());
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return field.getHiddenApiRestrictions();
}
}
}

View File

@ -31,6 +31,7 @@
package org.jf.dexlib2.rewriter;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Method;
@ -92,6 +93,10 @@ public class MethodRewriter implements Rewriter<Method> {
return RewriterUtils.rewriteSet(rewriters.getAnnotationRewriter(), method.getAnnotations());
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return method.getHiddenApiRestrictions();
}
@Override @Nullable public MethodImplementation getImplementation() {
return RewriterUtils.rewriteNullable(rewriters.getMethodImplementationRewriter(),
method.getImplementation());

View File

@ -31,12 +31,15 @@
package org.jf.dexlib2.writer.builder;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseFieldReference;
import org.jf.dexlib2.iface.Field;
import org.jf.dexlib2.writer.builder.BuilderEncodedValues.BuilderEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Set;
public class BuilderField extends BaseFieldReference implements Field {
@Nonnull final BuilderFieldReference fieldReference;
@ -77,4 +80,8 @@ public class BuilderField extends BaseFieldReference implements Field {
@Nonnull @Override public String getType() {
return fieldReference.fieldType.getType();
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return ImmutableSet.of();
}
}

View File

@ -31,6 +31,8 @@
package org.jf.dexlib2.writer.builder;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.Method;
import org.jf.dexlib2.iface.MethodImplementation;
@ -39,6 +41,7 @@ import org.jf.dexlib2.writer.DexWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;
public class BuilderMethod extends BaseMethodReference implements Method {
@Nonnull final BuilderMethodReference methodReference;
@ -69,5 +72,10 @@ public class BuilderMethod extends BaseMethodReference implements Method {
@Override @Nonnull public List<? extends BuilderMethodParameter> getParameters() { return parameters; }
@Override public int getAccessFlags() { return accessFlags; }
@Override @Nonnull public BuilderAnnotationSet getAnnotations() { return annotations; }
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return ImmutableSet.of();
}
@Override @Nullable public MethodImplementation getImplementation() { return methodImplementation; }
}

View File

@ -32,6 +32,7 @@
package org.jf.dexlib2.writer.pool;
import com.google.common.base.Function;
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Method;
@ -87,6 +88,10 @@ class PoolMethod extends BaseMethodReference implements Method {
return method.getAnnotations();
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
return method.getHiddenApiRestrictions();
}
@Override @Nullable public MethodImplementation getImplementation() {
return method.getImplementation();
}

View File

@ -60,7 +60,7 @@ public class CustomMethodInlineTableTest {
ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null);
ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PUBLIC.getValue(), null,
methodImpl);
null, methodImpl);
ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, null, null, ImmutableList.of(method));
@ -91,7 +91,7 @@ public class CustomMethodInlineTableTest {
ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null);
ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.STATIC.getValue(), null,
methodImpl);
null, methodImpl);
ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, null, ImmutableList.of(method), null);
@ -122,7 +122,7 @@ public class CustomMethodInlineTableTest {
ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null);
ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PRIVATE.getValue(), null,
methodImpl);
null, methodImpl);
ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, null, ImmutableList.of(method), null);

View File

@ -76,7 +76,7 @@ public class MethodAnalyzerTest {
Method method = new ImmutableMethod("Lmain;", "narrowing",
Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, methodImplementation);
AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, Collections.singletonList(method));
DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef));
@ -107,7 +107,7 @@ public class MethodAnalyzerTest {
Method method = new ImmutableMethod("Lmain;", "narrowing",
Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, methodImplementation);
AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, Collections.singletonList(method));
DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), Collections.singletonList(classDef));
@ -139,7 +139,7 @@ public class MethodAnalyzerTest {
Method method = new ImmutableMethod("Lmain;", "narrowing",
Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, methodImplementation);
AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, Collections.singletonList(method));
DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef));
@ -170,7 +170,7 @@ public class MethodAnalyzerTest {
Method method = new ImmutableMethod("Lmain;", "narrowing",
Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, methodImplementation);
AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, Collections.singletonList(method));
DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), Collections.singletonList(classDef));
@ -203,7 +203,7 @@ public class MethodAnalyzerTest {
Method method = new ImmutableMethod("Lmain;", "narrowing",
Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, methodImplementation);
AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, Collections.singletonList(method));
DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef));
@ -238,7 +238,7 @@ public class MethodAnalyzerTest {
Method method = new ImmutableMethod("Lmain;", "narrowing",
Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, methodImplementation);
AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, Collections.singletonList(method));
DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), Collections.singletonList(classDef));

View File

@ -56,23 +56,23 @@ public class RollbackTest {
ClassDef class1 = new ImmutableClassDef("Lcls1;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null,
Lists.newArrayList(new ImmutableAnnotation(AnnotationVisibility.RUNTIME, "Lannotation;", null)),
Lists.<Field>newArrayList(
new ImmutableField("Lcls1;", "field1", "I", AccessFlags.PUBLIC.getValue(), null, null)
new ImmutableField("Lcls1;", "field1", "I", AccessFlags.PUBLIC.getValue(), null, null, null)
),
Lists.<Method>newArrayList(
new ImmutableMethod("Lcls1", "method1",
Lists.<MethodParameter>newArrayList(new ImmutableMethodParameter("L", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, null))
AccessFlags.PUBLIC.getValue(), null, null, null))
);
ClassDef class2 = new ImmutableClassDef("Lcls2;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null,
Lists.newArrayList(new ImmutableAnnotation(AnnotationVisibility.RUNTIME, "Lannotation2;", null)),
Lists.<Field>newArrayList(
new ImmutableField("Lcls2;", "field2", "D", AccessFlags.PUBLIC.getValue(), null, null)
new ImmutableField("Lcls2;", "field2", "D", AccessFlags.PUBLIC.getValue(), null, null, null)
),
Lists.<Method>newArrayList(
new ImmutableMethod("Lcls2;", "method2",
Lists.<MethodParameter>newArrayList(new ImmutableMethodParameter("D", null, null)), "V",
AccessFlags.PUBLIC.getValue(), null, null))
AccessFlags.PUBLIC.getValue(), null, null, null))
);
DexBackedDexFile dexFile1;

View File

@ -70,7 +70,7 @@ public class CallSiteTest {
null, null,
Lists.<Method>newArrayList(
new ImmutableMethod("Lcls1", "method1",
ImmutableList.of(), "V", AccessFlags.PUBLIC.getValue(), null,
ImmutableList.of(), "V", AccessFlags.PUBLIC.getValue(), null, null,
new ImmutableMethodImplementation(10, ImmutableList.of(
new ImmutableInstruction35c(Opcode.INVOKE_CUSTOM, 0, 0, 0, 0, 0, 0,
new ImmutableCallSiteReference("call_site_1",