Merge "Hashtable: Use upstream OpenJDK8u121-b13 versions of Map default methods"
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index d348239..758b6ce 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -91,7 +91,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-all
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_REQUIRED_MODULES := tzdata
LOCAL_CORE_LIBRARY := true
LOCAL_UNINSTALLABLE_MODULE := true
@@ -109,7 +108,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-oj
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
LOCAL_REQUIRED_MODULES := tzdata
@@ -126,7 +124,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-libart
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
ifeq ($(EMMA_INSTRUMENT),true)
ifneq ($(EMMA_INSTRUMENT_STATIC),true)
@@ -148,7 +145,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-lambda-stubs
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
LOCAL_CORE_LIBRARY := true
@@ -169,7 +165,6 @@
LOCAL_DEX_PREOPT := false
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-oj-testdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
LOCAL_REQUIRED_MODULES := tzdata
@@ -204,7 +199,6 @@
LOCAL_DEX_PREOPT := false
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-libart-testdex
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_CORE_LIBRARY := true
LOCAL_REQUIRED_MODULES := tzdata
@@ -221,6 +215,9 @@
LOCAL_JAVA_LIBRARIES := core-oj core-libart
LOCAL_DEX_PREOPT := false
include $(BUILD_JAVA_LIBRARY)
+my_filesystemstest_jar := $(intermediates)/filesystemstest.jar
+$(my_filesystemstest_jar): $(LOCAL_BUILT_MODULE)
+ $(call copy-file-to-target)
endif
ifeq ($(LIBCORE_SKIP_TESTS),)
@@ -230,7 +227,7 @@
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
# Include individual dex.jar files (jars containing resources and a classes.dex) so that they
# be loaded by tests using ClassLoaders but are not in the main classes.dex.
-LOCAL_JAVA_RESOURCE_FILES := $(TARGET_OUT)/framework/filesystemstest.jar
+LOCAL_JAVA_RESOURCE_FILES := $(my_filesystemstest_jar)
LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp bouncycastle
LOCAL_STATIC_JAVA_LIBRARIES := \
@@ -248,7 +245,6 @@
LOCAL_ERROR_PRONE_FLAGS := -Xep:TryFailThrowable:ERROR
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-tests
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
endif
@@ -262,7 +258,6 @@
LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-bcpkix bouncycastle-ocsp
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE := core-tests-support
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
endif
@@ -276,7 +271,6 @@
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE := jsr166-tests
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
endif
@@ -292,7 +286,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-ojtests
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
# jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
include $(BUILD_JAVA_LIBRARY)
@@ -317,7 +310,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-ojtests-public
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
# jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
include $(BUILD_JAVA_LIBRARY)
@@ -330,12 +322,6 @@
ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, dex/src/main)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := dex-host
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(non_openjdk_java_files) $(openjdk_java_files) $(android_icu4j_src_files) $(openjdk_lambda_stub_files)
LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
@@ -344,7 +330,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-all-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_REQUIRED_MODULES := tzdata-host
LOCAL_CORE_LIBRARY := true
LOCAL_UNINSTALLABLE_MODULE := true
@@ -360,7 +345,6 @@
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-oj-hostdex
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all-hostdex
LOCAL_REQUIRED_MODULES := tzdata-host
LOCAL_CORE_LIBRARY := true
@@ -376,7 +360,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-libart-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-oj-hostdex
LOCAL_REQUIRED_MODULES := tzdata-host
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
@@ -391,7 +374,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-lambda-stubs-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all-hostdex
LOCAL_CORE_LIBRARY := true
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
@@ -423,7 +405,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-tests-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
endif
@@ -444,7 +425,6 @@
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := core-tests-support-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
endif
@@ -464,7 +444,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-ojtests-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
endif
@@ -502,7 +481,6 @@
LOCAL_MODULE_CLASS:=JAVA_LIBRARIES
LOCAL_MODULE := libcore
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_DROIDDOC_OPTIONS := \
-offlinemode \
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index b9e607a..3693bb2 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -441,8 +441,6 @@
} else if (file.isDirectory()) {
// We support directories for looking up native libraries.
elements[elementsPos++] = new NativeLibraryElement(file);
- } else {
- System.logW("ClassLoader referenced unknown path: " + file);
}
}
if (elementsPos != elements.length) {
diff --git a/dex/src/main/java/com/android/dex/Annotation.java b/dex/src/main/java/com/android/dex/Annotation.java
deleted file mode 100644
index e5ef978..0000000
--- a/dex/src/main/java/com/android/dex/Annotation.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import static com.android.dex.EncodedValueReader.ENCODED_ANNOTATION;
-
-/**
- * An annotation.
- */
-public final class Annotation implements Comparable<Annotation> {
- private final Dex dex;
- private final byte visibility;
- private final EncodedValue encodedAnnotation;
-
- public Annotation(Dex dex, byte visibility, EncodedValue encodedAnnotation) {
- this.dex = dex;
- this.visibility = visibility;
- this.encodedAnnotation = encodedAnnotation;
- }
-
- public byte getVisibility() {
- return visibility;
- }
-
- public EncodedValueReader getReader() {
- return new EncodedValueReader(encodedAnnotation, ENCODED_ANNOTATION);
- }
-
- public int getTypeIndex() {
- EncodedValueReader reader = getReader();
- reader.readAnnotation();
- return reader.getAnnotationType();
- }
-
- public void writeTo(Dex.Section out) {
- out.writeByte(visibility);
- encodedAnnotation.writeTo(out);
- }
-
- @Override public int compareTo(Annotation other) {
- return encodedAnnotation.compareTo(other.encodedAnnotation);
- }
-
- @Override public String toString() {
- return dex == null
- ? visibility + " " + getTypeIndex()
- : visibility + " " + dex.typeNames().get(getTypeIndex());
- }
-}
diff --git a/dex/src/main/java/com/android/dex/ClassData.java b/dex/src/main/java/com/android/dex/ClassData.java
deleted file mode 100644
index 840756c..0000000
--- a/dex/src/main/java/com/android/dex/ClassData.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-public final class ClassData {
- private final Field[] staticFields;
- private final Field[] instanceFields;
- private final Method[] directMethods;
- private final Method[] virtualMethods;
-
- public ClassData(Field[] staticFields, Field[] instanceFields,
- Method[] directMethods, Method[] virtualMethods) {
- this.staticFields = staticFields;
- this.instanceFields = instanceFields;
- this.directMethods = directMethods;
- this.virtualMethods = virtualMethods;
- }
-
- public Field[] getStaticFields() {
- return staticFields;
- }
-
- public Field[] getInstanceFields() {
- return instanceFields;
- }
-
- public Method[] getDirectMethods() {
- return directMethods;
- }
-
- public Method[] getVirtualMethods() {
- return virtualMethods;
- }
-
- public Field[] allFields() {
- Field[] result = new Field[staticFields.length + instanceFields.length];
- System.arraycopy(staticFields, 0, result, 0, staticFields.length);
- System.arraycopy(instanceFields, 0, result, staticFields.length, instanceFields.length);
- return result;
- }
-
- public Method[] allMethods() {
- Method[] result = new Method[directMethods.length + virtualMethods.length];
- System.arraycopy(directMethods, 0, result, 0, directMethods.length);
- System.arraycopy(virtualMethods, 0, result, directMethods.length, virtualMethods.length);
- return result;
- }
-
- public static class Field {
- private final int fieldIndex;
- private final int accessFlags;
-
- public Field(int fieldIndex, int accessFlags) {
- this.fieldIndex = fieldIndex;
- this.accessFlags = accessFlags;
- }
-
- public int getFieldIndex() {
- return fieldIndex;
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
- }
-
- public static class Method {
- private final int methodIndex;
- private final int accessFlags;
- private final int codeOffset;
-
- public Method(int methodIndex, int accessFlags, int codeOffset) {
- this.methodIndex = methodIndex;
- this.accessFlags = accessFlags;
- this.codeOffset = codeOffset;
- }
-
- public int getMethodIndex() {
- return methodIndex;
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- public int getCodeOffset() {
- return codeOffset;
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/ClassDef.java b/dex/src/main/java/com/android/dex/ClassDef.java
deleted file mode 100644
index b3225ec..0000000
--- a/dex/src/main/java/com/android/dex/ClassDef.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-/**
- * A type definition.
- */
-public final class ClassDef {
- public static final int NO_INDEX = -1;
- private final Dex buffer;
- private final int offset;
- private final int typeIndex;
- private final int accessFlags;
- private final int supertypeIndex;
- private final int interfacesOffset;
- private final int sourceFileIndex;
- private final int annotationsOffset;
- private final int classDataOffset;
- private final int staticValuesOffset;
-
- public ClassDef(Dex buffer, int offset, int typeIndex, int accessFlags,
- int supertypeIndex, int interfacesOffset, int sourceFileIndex,
- int annotationsOffset, int classDataOffset, int staticValuesOffset) {
- this.buffer = buffer;
- this.offset = offset;
- this.typeIndex = typeIndex;
- this.accessFlags = accessFlags;
- this.supertypeIndex = supertypeIndex;
- this.interfacesOffset = interfacesOffset;
- this.sourceFileIndex = sourceFileIndex;
- this.annotationsOffset = annotationsOffset;
- this.classDataOffset = classDataOffset;
- this.staticValuesOffset = staticValuesOffset;
- }
-
- public int getOffset() {
- return offset;
- }
-
- public int getTypeIndex() {
- return typeIndex;
- }
-
- public int getSupertypeIndex() {
- return supertypeIndex;
- }
-
- public int getInterfacesOffset() {
- return interfacesOffset;
- }
-
- public short[] getInterfaces() {
- return buffer.readTypeList(interfacesOffset).getTypes();
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- public int getSourceFileIndex() {
- return sourceFileIndex;
- }
-
- public int getAnnotationsOffset() {
- return annotationsOffset;
- }
-
- public int getClassDataOffset() {
- return classDataOffset;
- }
-
- public int getStaticValuesOffset() {
- return staticValuesOffset;
- }
-
- @Override public String toString() {
- if (buffer == null) {
- return typeIndex + " " + supertypeIndex;
- }
-
- StringBuilder result = new StringBuilder();
- result.append(buffer.typeNames().get(typeIndex));
- if (supertypeIndex != NO_INDEX) {
- result.append(" extends ").append(buffer.typeNames().get(supertypeIndex));
- }
- return result.toString();
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Code.java b/dex/src/main/java/com/android/dex/Code.java
deleted file mode 100644
index 9258af7..0000000
--- a/dex/src/main/java/com/android/dex/Code.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-public final class Code {
- private final int registersSize;
- private final int insSize;
- private final int outsSize;
- private final int debugInfoOffset;
- private final short[] instructions;
- private final Try[] tries;
- private final CatchHandler[] catchHandlers;
-
- public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset,
- short[] instructions, Try[] tries, CatchHandler[] catchHandlers) {
- this.registersSize = registersSize;
- this.insSize = insSize;
- this.outsSize = outsSize;
- this.debugInfoOffset = debugInfoOffset;
- this.instructions = instructions;
- this.tries = tries;
- this.catchHandlers = catchHandlers;
- }
-
- public int getRegistersSize() {
- return registersSize;
- }
-
- public int getInsSize() {
- return insSize;
- }
-
- public int getOutsSize() {
- return outsSize;
- }
-
- public int getDebugInfoOffset() {
- return debugInfoOffset;
- }
-
- public short[] getInstructions() {
- return instructions;
- }
-
- public Try[] getTries() {
- return tries;
- }
-
- public CatchHandler[] getCatchHandlers() {
- return catchHandlers;
- }
-
- public static class Try {
- final int startAddress;
- final int instructionCount;
- final int catchHandlerIndex;
-
- Try(int startAddress, int instructionCount, int catchHandlerIndex) {
- this.startAddress = startAddress;
- this.instructionCount = instructionCount;
- this.catchHandlerIndex = catchHandlerIndex;
- }
-
- public int getStartAddress() {
- return startAddress;
- }
-
- public int getInstructionCount() {
- return instructionCount;
- }
-
- /**
- * Returns this try's catch handler <strong>index</strong>. Note that
- * this is distinct from the its catch handler <strong>offset</strong>.
- */
- public int getCatchHandlerIndex() {
- return catchHandlerIndex;
- }
- }
-
- public static class CatchHandler {
- final int[] typeIndexes;
- final int[] addresses;
- final int catchAllAddress;
- final int offset;
-
- public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress, int offset) {
- this.typeIndexes = typeIndexes;
- this.addresses = addresses;
- this.catchAllAddress = catchAllAddress;
- this.offset = offset;
- }
-
- public int[] getTypeIndexes() {
- return typeIndexes;
- }
-
- public int[] getAddresses() {
- return addresses;
- }
-
- public int getCatchAllAddress() {
- return catchAllAddress;
- }
-
- public int getOffset() {
- return offset;
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Dex.java b/dex/src/main/java/com/android/dex/Dex.java
deleted file mode 100644
index 59e5ffb..0000000
--- a/dex/src/main/java/com/android/dex/Dex.java
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.Code.CatchHandler;
-import com.android.dex.Code.Try;
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-import com.android.dex.util.FileUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UTFDataFormatException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.AbstractList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.RandomAccess;
-import java.util.zip.Adler32;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * The bytes of a dex file in memory for reading and writing. All int offsets
- * are unsigned.
- */
-public final class Dex {
- private static final int CHECKSUM_OFFSET = 8;
- private static final int CHECKSUM_SIZE = 4;
- private static final int SIGNATURE_OFFSET = CHECKSUM_OFFSET + CHECKSUM_SIZE;
- private static final int SIGNATURE_SIZE = 20;
- // Provided as a convenience to avoid a memory allocation to benefit Dalvik.
- // Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik.
- static final short[] EMPTY_SHORT_ARRAY = new short[0];
-
- private ByteBuffer data;
- private final TableOfContents tableOfContents = new TableOfContents();
- private int nextSectionStart = 0;
- private final StringTable strings = new StringTable();
- private final TypeIndexToDescriptorIndexTable typeIds = new TypeIndexToDescriptorIndexTable();
- private final TypeIndexToDescriptorTable typeNames = new TypeIndexToDescriptorTable();
- private final ProtoIdTable protoIds = new ProtoIdTable();
- private final FieldIdTable fieldIds = new FieldIdTable();
- private final MethodIdTable methodIds = new MethodIdTable();
-
- /**
- * Creates a new dex that reads from {@code data}. It is an error to modify
- * {@code data} after using it to create a dex buffer.
- */
- public Dex(byte[] data) throws IOException {
- this(ByteBuffer.wrap(data));
- }
-
- private Dex(ByteBuffer data) throws IOException {
- this.data = data;
- this.data.order(ByteOrder.LITTLE_ENDIAN);
- this.tableOfContents.readFrom(this);
- }
-
- /**
- * Creates a new empty dex of the specified size.
- */
- public Dex(int byteCount) throws IOException {
- this.data = ByteBuffer.wrap(new byte[byteCount]);
- this.data.order(ByteOrder.LITTLE_ENDIAN);
- }
-
- /**
- * Creates a new dex buffer of the dex in {@code in}, and closes {@code in}.
- */
- public Dex(InputStream in) throws IOException {
- try {
- loadFrom(in);
- } finally {
- in.close();
- }
- }
-
- /**
- * Creates a new dex buffer from the dex file {@code file}.
- */
- public Dex(File file) throws IOException {
- if (FileUtils.hasArchiveSuffix(file.getName())) {
- ZipFile zipFile = new ZipFile(file);
- ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);
- if (entry != null) {
- try (InputStream inputStream = zipFile.getInputStream(entry)) {
- loadFrom(inputStream);
- }
- zipFile.close();
- } else {
- throw new DexException("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file);
- }
- } else if (file.getName().endsWith(".dex")) {
- try (InputStream inputStream = new FileInputStream(file)) {
- loadFrom(inputStream);
- }
- } else {
- throw new DexException("unknown output extension: " + file);
- }
- }
-
- /**
- * Creates a new dex from the contents of {@code bytes}. This API supports
- * both {@code .dex} and {@code .odex} input. Calling this constructor
- * transfers ownership of {@code bytes} to the returned Dex: it is an error
- * to access the buffer after calling this method.
- *
- * NOTE: This method is called by the runtime.
- */
- public static Dex create(ByteBuffer data) throws IOException {
- data.order(ByteOrder.LITTLE_ENDIAN);
-
- // if it's an .odex file, set position and limit to the .dex section
- if (data.get(0) == 'd'
- && data.get(1) == 'e'
- && data.get(2) == 'y'
- && data.get(3) == '\n') {
- data.position(8);
- int offset = data.getInt();
- int length = data.getInt();
- data.position(offset);
- data.limit(offset + length);
- data = data.slice();
- }
-
- return new Dex(data);
- }
-
- /**
- * It is the caller's responsibility to close {@code in}.
- */
- private void loadFrom(InputStream in) throws IOException {
- ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
- byte[] buffer = new byte[8192];
-
- int count;
- while ((count = in.read(buffer)) != -1) {
- bytesOut.write(buffer, 0, count);
- }
-
- this.data = ByteBuffer.wrap(bytesOut.toByteArray());
- this.data.order(ByteOrder.LITTLE_ENDIAN);
- this.tableOfContents.readFrom(this);
- }
-
- private static void checkBounds(int index, int length) {
- if (index < 0 || index >= length) {
- throw new IndexOutOfBoundsException("index:" + index + ", length=" + length);
- }
- }
-
- public void writeTo(OutputStream out) throws IOException {
- byte[] buffer = new byte[8192];
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- data.clear();
- while (data.hasRemaining()) {
- int count = Math.min(buffer.length, data.remaining());
- data.get(buffer, 0, count);
- out.write(buffer, 0, count);
- }
- }
-
- public void writeTo(File dexOut) throws IOException {
- try (OutputStream out = new FileOutputStream(dexOut)) {
- writeTo(out);
- }
- }
-
- public TableOfContents getTableOfContents() {
- return tableOfContents;
- }
-
- public Section open(int position) {
- if (position < 0 || position >= data.capacity()) {
- throw new IllegalArgumentException("position=" + position
- + " length=" + data.capacity());
- }
- ByteBuffer sectionData = data.duplicate();
- sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
- sectionData.position(position);
- sectionData.limit(data.capacity());
- return new Section("section", sectionData);
- }
-
- public Section appendSection(int maxByteCount, String name) {
- if ((maxByteCount & 3) != 0) {
- throw new IllegalStateException("Not four byte aligned!");
- }
- int limit = nextSectionStart + maxByteCount;
- ByteBuffer sectionData = data.duplicate();
- sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
- sectionData.position(nextSectionStart);
- sectionData.limit(limit);
- Section result = new Section(name, sectionData);
- nextSectionStart = limit;
- return result;
- }
-
- public int getLength() {
- return data.capacity();
- }
-
- public int getNextSectionStart() {
- return nextSectionStart;
- }
-
- /**
- * Returns a copy of the the bytes of this dex.
- */
- public byte[] getBytes() {
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- byte[] result = new byte[data.capacity()];
- data.position(0);
- data.get(result);
- return result;
- }
-
- public List<String> strings() {
- return strings;
- }
-
- public List<Integer> typeIds() {
- return typeIds;
- }
-
- public List<String> typeNames() {
- return typeNames;
- }
-
- public List<ProtoId> protoIds() {
- return protoIds;
- }
-
- public List<FieldId> fieldIds() {
- return fieldIds;
- }
-
- public List<MethodId> methodIds() {
- return methodIds;
- }
-
- public Iterable<ClassDef> classDefs() {
- return new ClassDefIterable();
- }
-
- public TypeList readTypeList(int offset) {
- if (offset == 0) {
- return TypeList.EMPTY;
- }
- return open(offset).readTypeList();
- }
-
- public ClassData readClassData(ClassDef classDef) {
- int offset = classDef.getClassDataOffset();
- if (offset == 0) {
- throw new IllegalArgumentException("offset == 0");
- }
- return open(offset).readClassData();
- }
-
- public Code readCode(ClassData.Method method) {
- int offset = method.getCodeOffset();
- if (offset == 0) {
- throw new IllegalArgumentException("offset == 0");
- }
- return open(offset).readCode();
- }
-
- /**
- * Returns the signature of all but the first 32 bytes of this dex. The
- * first 32 bytes of dex files are not specified to be included in the
- * signature.
- */
- public byte[] computeSignature() throws IOException {
- MessageDigest digest;
- try {
- digest = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError();
- }
- byte[] buffer = new byte[8192];
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- data.limit(data.capacity());
- data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE);
- while (data.hasRemaining()) {
- int count = Math.min(buffer.length, data.remaining());
- data.get(buffer, 0, count);
- digest.update(buffer, 0, count);
- }
- return digest.digest();
- }
-
- /**
- * Returns the checksum of all but the first 12 bytes of {@code dex}.
- */
- public int computeChecksum() throws IOException {
- Adler32 adler32 = new Adler32();
- byte[] buffer = new byte[8192];
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- data.limit(data.capacity());
- data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE);
- while (data.hasRemaining()) {
- int count = Math.min(buffer.length, data.remaining());
- data.get(buffer, 0, count);
- adler32.update(buffer, 0, count);
- }
- return (int) adler32.getValue();
- }
-
- /**
- * Generates the signature and checksum of the dex file {@code out} and
- * writes them to the file.
- */
- public void writeHashes() throws IOException {
- open(SIGNATURE_OFFSET).write(computeSignature());
- open(CHECKSUM_OFFSET).writeInt(computeChecksum());
- }
-
- /**
- * Look up a field id name index from a field index. Cheaper than:
- * {@code fieldIds().get(fieldDexIndex).getNameIndex();}
- */
- public int nameIndexFromFieldIndex(int fieldIndex) {
- checkBounds(fieldIndex, tableOfContents.fieldIds.size);
- int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);
- position += SizeOf.USHORT; // declaringClassIndex
- position += SizeOf.USHORT; // typeIndex
- return data.getInt(position); // nameIndex
- }
-
- /**
- * Look up a method id name index from a method index. Cheaper than:
- * {@code methodIds().get(methodIndex).getNameIndex();}
- */
- public int nameIndexFromMethodIndex(int methodIndex) {
- checkBounds(methodIndex, tableOfContents.methodIds.size);
- int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
- position += SizeOf.USHORT; // declaringClassIndex
- position += SizeOf.USHORT; // protoIndex
- return data.getInt(position); // nameIndex
- }
-
- /**
- * Look up a parameter type ids from a method index. Cheaper than:
- * {@code readTypeList(protoIds.get(methodIds().get(methodDexIndex).getProtoIndex()).getParametersOffset()).getTypes();}
- */
- public short[] parameterTypeIndicesFromMethodIndex(int methodIndex) {
- checkBounds(methodIndex, tableOfContents.methodIds.size);
- int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
- position += SizeOf.USHORT; // declaringClassIndex
- int protoIndex = data.getShort(position) & 0xFFFF;
- checkBounds(protoIndex, tableOfContents.protoIds.size);
- position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);
- position += SizeOf.UINT; // shortyIndex
- position += SizeOf.UINT; // returnTypeIndex
- int parametersOffset = data.getInt(position);
- if (parametersOffset == 0) {
- return EMPTY_SHORT_ARRAY;
- }
- position = parametersOffset;
- int size = data.getInt(position);
- if (size <= 0) {
- throw new AssertionError("Unexpected parameter type list size: " + size);
- }
- position += SizeOf.UINT;
- short[] types = new short[size];
- for (int i = 0; i < size; i++) {
- types[i] = data.getShort(position);
- position += SizeOf.USHORT;
- }
- return types;
- }
-
- /**
- * Look up a method id return type index from a method index. Cheaper than:
- * {@code protoIds().get(methodIds().get(methodDexIndex).getProtoIndex()).getReturnTypeIndex();}
- */
- public int returnTypeIndexFromMethodIndex(int methodIndex) {
- checkBounds(methodIndex, tableOfContents.methodIds.size);
- int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
- position += SizeOf.USHORT; // declaringClassIndex
- int protoIndex = data.getShort(position) & 0xFFFF;
- checkBounds(protoIndex, tableOfContents.protoIds.size);
- position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);
- position += SizeOf.UINT; // shortyIndex
- return data.getInt(position); // returnTypeIndex
- }
-
- /**
- * Look up a descriptor index from a type index. Cheaper than:
- * {@code open(tableOfContents.typeIds.off + (index * SizeOf.TYPE_ID_ITEM)).readInt();}
- */
- public int descriptorIndexFromTypeIndex(int typeIndex) {
- checkBounds(typeIndex, tableOfContents.typeIds.size);
- int position = tableOfContents.typeIds.off + (SizeOf.TYPE_ID_ITEM * typeIndex);
- return data.getInt(position);
- }
-
- /**
- * Look up interface types indices from a return type index from a method index. Cheaper than:
- * {@code ...getClassDef(classDefIndex).getInterfaces();}
- */
- public short[] interfaceTypeIndicesFromClassDefIndex(int classDefIndex) {
- checkBounds(classDefIndex, tableOfContents.classDefs.size);
- int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);
- position += SizeOf.UINT; // type
- position += SizeOf.UINT; // accessFlags
- position += SizeOf.UINT; // superType
- int interfacesOffset = data.getInt(position);
- if (interfacesOffset == 0) {
- return EMPTY_SHORT_ARRAY;
- }
- position = interfacesOffset;
- int size = data.getInt(position);
- if (size <= 0) {
- throw new AssertionError("Unexpected interfaces list size: " + size);
- }
- position += SizeOf.UINT;
- short[] types = new short[size];
- for (int i = 0; i < size; i++) {
- types[i] = data.getShort(position);
- position += SizeOf.USHORT;
- }
- return types;
- }
-
- public final class Section implements ByteInput, ByteOutput {
- private final String name;
- private final ByteBuffer data;
- private final int initialPosition;
-
- private Section(String name, ByteBuffer data) {
- this.name = name;
- this.data = data;
- this.initialPosition = data.position();
- }
-
- public int getPosition() {
- return data.position();
- }
-
- public int readInt() {
- return data.getInt();
- }
-
- public short readShort() {
- return data.getShort();
- }
-
- public int readUnsignedShort() {
- return readShort() & 0xffff;
- }
-
- public byte readByte() {
- return data.get();
- }
-
- public byte[] readByteArray(int length) {
- byte[] result = new byte[length];
- data.get(result);
- return result;
- }
-
- public short[] readShortArray(int length) {
- if (length == 0) {
- return EMPTY_SHORT_ARRAY;
- }
- short[] result = new short[length];
- for (int i = 0; i < length; i++) {
- result[i] = readShort();
- }
- return result;
- }
-
- public int readUleb128() {
- return Leb128.readUnsignedLeb128(this);
- }
-
- public int readUleb128p1() {
- return Leb128.readUnsignedLeb128(this) - 1;
- }
-
- public int readSleb128() {
- return Leb128.readSignedLeb128(this);
- }
-
- public void writeUleb128p1(int i) {
- writeUleb128(i + 1);
- }
-
- public TypeList readTypeList() {
- int size = readInt();
- short[] types = readShortArray(size);
- alignToFourBytes();
- return new TypeList(Dex.this, types);
- }
-
- public String readString() {
- int offset = readInt();
- int savedPosition = data.position();
- int savedLimit = data.limit();
- data.position(offset);
- data.limit(data.capacity());
- try {
- int expectedLength = readUleb128();
- String result = Mutf8.decode(this, new char[expectedLength]);
- if (result.length() != expectedLength) {
- throw new DexException("Declared length " + expectedLength
- + " doesn't match decoded length of " + result.length());
- }
- return result;
- } catch (UTFDataFormatException e) {
- throw new DexException(e);
- } finally {
- data.position(savedPosition);
- data.limit(savedLimit);
- }
- }
-
- public FieldId readFieldId() {
- int declaringClassIndex = readUnsignedShort();
- int typeIndex = readUnsignedShort();
- int nameIndex = readInt();
- return new FieldId(Dex.this, declaringClassIndex, typeIndex, nameIndex);
- }
-
- public MethodId readMethodId() {
- int declaringClassIndex = readUnsignedShort();
- int protoIndex = readUnsignedShort();
- int nameIndex = readInt();
- return new MethodId(Dex.this, declaringClassIndex, protoIndex, nameIndex);
- }
-
- public ProtoId readProtoId() {
- int shortyIndex = readInt();
- int returnTypeIndex = readInt();
- int parametersOffset = readInt();
- return new ProtoId(Dex.this, shortyIndex, returnTypeIndex, parametersOffset);
- }
-
- public ClassDef readClassDef() {
- int offset = getPosition();
- int type = readInt();
- int accessFlags = readInt();
- int supertype = readInt();
- int interfacesOffset = readInt();
- int sourceFileIndex = readInt();
- int annotationsOffset = readInt();
- int classDataOffset = readInt();
- int staticValuesOffset = readInt();
- return new ClassDef(Dex.this, offset, type, accessFlags, supertype,
- interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset,
- staticValuesOffset);
- }
-
- private Code readCode() {
- int registersSize = readUnsignedShort();
- int insSize = readUnsignedShort();
- int outsSize = readUnsignedShort();
- int triesSize = readUnsignedShort();
- int debugInfoOffset = readInt();
- int instructionsSize = readInt();
- short[] instructions = readShortArray(instructionsSize);
- Try[] tries;
- CatchHandler[] catchHandlers;
- if (triesSize > 0) {
- if (instructions.length % 2 == 1) {
- readShort(); // padding
- }
-
- /*
- * We can't read the tries until we've read the catch handlers.
- * Unfortunately they're in the opposite order in the dex file
- * so we need to read them out-of-order.
- */
- Section triesSection = open(data.position());
- skip(triesSize * SizeOf.TRY_ITEM);
- catchHandlers = readCatchHandlers();
- tries = triesSection.readTries(triesSize, catchHandlers);
- } else {
- tries = new Try[0];
- catchHandlers = new CatchHandler[0];
- }
- return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
- tries, catchHandlers);
- }
-
- private CatchHandler[] readCatchHandlers() {
- int baseOffset = data.position();
- int catchHandlersSize = readUleb128();
- CatchHandler[] result = new CatchHandler[catchHandlersSize];
- for (int i = 0; i < catchHandlersSize; i++) {
- int offset = data.position() - baseOffset;
- result[i] = readCatchHandler(offset);
- }
- return result;
- }
-
- private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {
- Try[] result = new Try[triesSize];
- for (int i = 0; i < triesSize; i++) {
- int startAddress = readInt();
- int instructionCount = readUnsignedShort();
- int handlerOffset = readUnsignedShort();
- int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);
- result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);
- }
- return result;
- }
-
- private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {
- for (int i = 0; i < catchHandlers.length; i++) {
- CatchHandler catchHandler = catchHandlers[i];
- if (catchHandler.getOffset() == offset) {
- return i;
- }
- }
- throw new IllegalArgumentException();
- }
-
- private CatchHandler readCatchHandler(int offset) {
- int size = readSleb128();
- int handlersCount = Math.abs(size);
- int[] typeIndexes = new int[handlersCount];
- int[] addresses = new int[handlersCount];
- for (int i = 0; i < handlersCount; i++) {
- typeIndexes[i] = readUleb128();
- addresses[i] = readUleb128();
- }
- int catchAllAddress = size <= 0 ? readUleb128() : -1;
- return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);
- }
-
- private ClassData readClassData() {
- int staticFieldsSize = readUleb128();
- int instanceFieldsSize = readUleb128();
- int directMethodsSize = readUleb128();
- int virtualMethodsSize = readUleb128();
- ClassData.Field[] staticFields = readFields(staticFieldsSize);
- ClassData.Field[] instanceFields = readFields(instanceFieldsSize);
- ClassData.Method[] directMethods = readMethods(directMethodsSize);
- ClassData.Method[] virtualMethods = readMethods(virtualMethodsSize);
- return new ClassData(staticFields, instanceFields, directMethods, virtualMethods);
- }
-
- private ClassData.Field[] readFields(int count) {
- ClassData.Field[] result = new ClassData.Field[count];
- int fieldIndex = 0;
- for (int i = 0; i < count; i++) {
- fieldIndex += readUleb128(); // field index diff
- int accessFlags = readUleb128();
- result[i] = new ClassData.Field(fieldIndex, accessFlags);
- }
- return result;
- }
-
- private ClassData.Method[] readMethods(int count) {
- ClassData.Method[] result = new ClassData.Method[count];
- int methodIndex = 0;
- for (int i = 0; i < count; i++) {
- methodIndex += readUleb128(); // method index diff
- int accessFlags = readUleb128();
- int codeOff = readUleb128();
- result[i] = new ClassData.Method(methodIndex, accessFlags, codeOff);
- }
- return result;
- }
-
- /**
- * Returns a byte array containing the bytes from {@code start} to this
- * section's current position.
- */
- private byte[] getBytesFrom(int start) {
- int end = data.position();
- byte[] result = new byte[end - start];
- data.position(start);
- data.get(result);
- return result;
- }
-
- public Annotation readAnnotation() {
- byte visibility = readByte();
- int start = data.position();
- new EncodedValueReader(this, EncodedValueReader.ENCODED_ANNOTATION).skipValue();
- return new Annotation(Dex.this, visibility, new EncodedValue(getBytesFrom(start)));
- }
-
- public EncodedValue readEncodedArray() {
- int start = data.position();
- new EncodedValueReader(this, EncodedValueReader.ENCODED_ARRAY).skipValue();
- return new EncodedValue(getBytesFrom(start));
- }
-
- public void skip(int count) {
- if (count < 0) {
- throw new IllegalArgumentException();
- }
- data.position(data.position() + count);
- }
-
- /**
- * Skips bytes until the position is aligned to a multiple of 4.
- */
- public void alignToFourBytes() {
- data.position((data.position() + 3) & ~3);
- }
-
- /**
- * Writes 0x00 until the position is aligned to a multiple of 4.
- */
- public void alignToFourBytesWithZeroFill() {
- while ((data.position() & 3) != 0) {
- data.put((byte) 0);
- }
- }
-
- public void assertFourByteAligned() {
- if ((data.position() & 3) != 0) {
- throw new IllegalStateException("Not four byte aligned!");
- }
- }
-
- public void write(byte[] bytes) {
- this.data.put(bytes);
- }
-
- public void writeByte(int b) {
- data.put((byte) b);
- }
-
- public void writeShort(short i) {
- data.putShort(i);
- }
-
- public void writeUnsignedShort(int i) {
- short s = (short) i;
- if (i != (s & 0xffff)) {
- throw new IllegalArgumentException("Expected an unsigned short: " + i);
- }
- writeShort(s);
- }
-
- public void write(short[] shorts) {
- for (short s : shorts) {
- writeShort(s);
- }
- }
-
- public void writeInt(int i) {
- data.putInt(i);
- }
-
- public void writeUleb128(int i) {
- try {
- Leb128.writeUnsignedLeb128(this, i);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
- }
- }
-
- public void writeSleb128(int i) {
- try {
- Leb128.writeSignedLeb128(this, i);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
- }
- }
-
- public void writeStringData(String value) {
- try {
- int length = value.length();
- writeUleb128(length);
- write(Mutf8.encode(value));
- writeByte(0);
- } catch (UTFDataFormatException e) {
- throw new AssertionError();
- }
- }
-
- public void writeTypeList(TypeList typeList) {
- short[] types = typeList.getTypes();
- writeInt(types.length);
- for (short type : types) {
- writeShort(type);
- }
- alignToFourBytesWithZeroFill();
- }
-
- /**
- * Returns the number of bytes used by this section.
- */
- public int used() {
- return data.position() - initialPosition;
- }
- }
-
- private final class StringTable extends AbstractList<String> implements RandomAccess {
- @Override public String get(int index) {
- checkBounds(index, tableOfContents.stringIds.size);
- return open(tableOfContents.stringIds.off + (index * SizeOf.STRING_ID_ITEM))
- .readString();
- }
- @Override public int size() {
- return tableOfContents.stringIds.size;
- }
- }
-
- private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer>
- implements RandomAccess {
- @Override public Integer get(int index) {
- return descriptorIndexFromTypeIndex(index);
- }
- @Override public int size() {
- return tableOfContents.typeIds.size;
- }
- }
-
- private final class TypeIndexToDescriptorTable extends AbstractList<String>
- implements RandomAccess {
- @Override public String get(int index) {
- return strings.get(descriptorIndexFromTypeIndex(index));
- }
- @Override public int size() {
- return tableOfContents.typeIds.size;
- }
- }
-
- private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {
- @Override public ProtoId get(int index) {
- checkBounds(index, tableOfContents.protoIds.size);
- return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index))
- .readProtoId();
- }
- @Override public int size() {
- return tableOfContents.protoIds.size;
- }
- }
-
- private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {
- @Override public FieldId get(int index) {
- checkBounds(index, tableOfContents.fieldIds.size);
- return open(tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * index))
- .readFieldId();
- }
- @Override public int size() {
- return tableOfContents.fieldIds.size;
- }
- }
-
- private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {
- @Override public MethodId get(int index) {
- checkBounds(index, tableOfContents.methodIds.size);
- return open(tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * index))
- .readMethodId();
- }
- @Override public int size() {
- return tableOfContents.methodIds.size;
- }
- }
-
- private final class ClassDefIterator implements Iterator<ClassDef> {
- private final Dex.Section in = open(tableOfContents.classDefs.off);
- private int count = 0;
-
- @Override
- public boolean hasNext() {
- return count < tableOfContents.classDefs.size;
- }
- @Override
- public ClassDef next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- count++;
- return in.readClassDef();
- }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- private final class ClassDefIterable implements Iterable<ClassDef> {
- public Iterator<ClassDef> iterator() {
- return !tableOfContents.classDefs.exists()
- ? Collections.<ClassDef>emptySet().iterator()
- : new ClassDefIterator();
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/DexException.java b/dex/src/main/java/com/android/dex/DexException.java
deleted file mode 100644
index ee0af18..0000000
--- a/dex/src/main/java/com/android/dex/DexException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.ExceptionWithContext;
-
-/**
- * Thrown when there's a format problem reading, writing, or generally
- * processing a dex file.
- */
-public class DexException extends ExceptionWithContext {
- public DexException(String message) {
- super(message);
- }
-
- public DexException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/DexFormat.java b/dex/src/main/java/com/android/dex/DexFormat.java
deleted file mode 100644
index 97771d8..0000000
--- a/dex/src/main/java/com/android/dex/DexFormat.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-/**
- * Constants that show up in and are otherwise related to {@code .dex}
- * files, and helper methods for same.
- */
-public final class DexFormat {
- private DexFormat() {}
-
- /** API level to target in order to generate invoke-polymorphic */
- public static final int API_INVOKE_POLYMORPHIC = 26;
-
- /** API level to target in order to pass through default and static interface methods */
- public static final int API_DEFAULT_INTERFACE_METHODS = 24;
-
- /** API level to target in order to suppress extended opcode usage */
- public static final int API_NO_EXTENDED_OPCODES = 13;
-
- /**
- * API level to target in order to produce the most modern file
- * format
- */
- public static final int API_CURRENT = API_INVOKE_POLYMORPHIC;
-
- /** dex file version number for API level 26 and earlier */
- public static final String VERSION_FOR_API_26 = "038";
-
- /** dex file version number for API level 24 and earlier */
- public static final String VERSION_FOR_API_24 = "037";
-
- /** dex file version number for API level 13 and earlier */
- public static final String VERSION_FOR_API_13 = "035";
-
- /**
- * Dex file version number for dalvik.
- * <p>
- * Note: Dex version 36 was loadable in some versions of Dalvik but was never fully supported or
- * completed and is not considered a valid dex file format.
- * </p>
- */
- public static final String VERSION_CURRENT = VERSION_FOR_API_26;
-
- /**
- * file name of the primary {@code .dex} file inside an
- * application or library {@code .jar} file
- */
- public static final String DEX_IN_JAR_NAME = "classes.dex";
-
- /** common prefix for all dex file "magic numbers" */
- public static final String MAGIC_PREFIX = "dex\n";
-
- /** common suffix for all dex file "magic numbers" */
- public static final String MAGIC_SUFFIX = "\0";
-
- /**
- * value used to indicate endianness of file contents
- */
- public static final int ENDIAN_TAG = 0x12345678;
-
- /**
- * Maximum addressable field or method index.
- * The largest addressable member is 0xffff, in the "instruction formats" spec as field@CCCC or
- * meth@CCCC.
- */
- public static final int MAX_MEMBER_IDX = 0xFFFF;
-
- /**
- * Maximum addressable type index.
- * The largest addressable type is 0xffff, in the "instruction formats" spec as type@CCCC.
- */
- public static final int MAX_TYPE_IDX = 0xFFFF;
-
- /**
- * Returns the API level corresponding to the given magic number,
- * or {@code -1} if the given array is not a well-formed dex file
- * magic number.
- */
- public static int magicToApi(byte[] magic) {
- if (magic.length != 8) {
- return -1;
- }
-
- if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\n') ||
- (magic[7] != '\0')) {
- return -1;
- }
-
- String version = "" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);
-
- if (version.equals(VERSION_FOR_API_13)) {
- return API_NO_EXTENDED_OPCODES;
- } else if (version.equals(VERSION_FOR_API_24)) {
- return API_DEFAULT_INTERFACE_METHODS;
- } else if (version.equals(VERSION_FOR_API_26)) {
- return API_INVOKE_POLYMORPHIC;
- } else if (version.equals(VERSION_CURRENT)) {
- return API_CURRENT;
- }
-
- return -1;
- }
-
- /**
- * Returns the magic number corresponding to the given target API level.
- */
- public static String apiToMagic(int targetApiLevel) {
- String version;
-
- if (targetApiLevel >= API_CURRENT) {
- version = VERSION_CURRENT;
- } else if (targetApiLevel >= API_INVOKE_POLYMORPHIC) {
- version = VERSION_FOR_API_26;
- } else if (targetApiLevel >= API_DEFAULT_INTERFACE_METHODS) {
- version = VERSION_FOR_API_24;
- } else {
- version = VERSION_FOR_API_13;
- }
-
- return MAGIC_PREFIX + version + MAGIC_SUFFIX;
- }
-
- public static boolean isSupportedDexMagic(byte[] magic) {
- int api = magicToApi(magic);
- return api > 0;
- }
-}
diff --git a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java b/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
deleted file mode 100644
index 3226207..0000000
--- a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-/**
- * Thrown when there's an index overflow writing a dex file.
- */
-public final class DexIndexOverflowException extends DexException {
- public DexIndexOverflowException(String message) {
- super(message);
- }
-
- public DexIndexOverflowException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValue.java b/dex/src/main/java/com/android/dex/EncodedValue.java
deleted file mode 100644
index 8d0c3ad..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValue.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.ByteArrayByteInput;
-import com.android.dex.util.ByteInput;
-
-/**
- * An encoded value or array.
- */
-public final class EncodedValue implements Comparable<EncodedValue> {
- private final byte[] data;
-
- public EncodedValue(byte[] data) {
- this.data = data;
- }
-
- public ByteInput asByteInput() {
- return new ByteArrayByteInput(data);
- }
-
- public byte[] getBytes() {
- return data;
- }
-
- public void writeTo(Dex.Section out) {
- out.write(data);
- }
-
- @Override public int compareTo(EncodedValue other) {
- int size = Math.min(data.length, other.data.length);
- for (int i = 0; i < size; i++) {
- if (data[i] != other.data[i]) {
- return (data[i] & 0xff) - (other.data[i] & 0xff);
- }
- }
- return data.length - other.data.length;
- }
-
- @Override public String toString() {
- return Integer.toHexString(data[0] & 0xff) + "...(" + data.length + ")";
- }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValueCodec.java b/dex/src/main/java/com/android/dex/EncodedValueCodec.java
deleted file mode 100644
index 7fc1724..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValueCodec.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-
-/**
- * Read and write {@code encoded_value} primitives.
- */
-public final class EncodedValueCodec {
- private EncodedValueCodec() {
- }
-
- /**
- * Writes a signed integral to {@code out}.
- */
- public static void writeSignedIntegralValue(ByteOutput out, int type, long value) {
- /*
- * Figure out how many bits are needed to represent the value,
- * including a sign bit: The bit count is subtracted from 65
- * and not 64 to account for the sign bit. The xor operation
- * has the effect of leaving non-negative values alone and
- * unary complementing negative values (so that a leading zero
- * count always returns a useful number for our present
- * purpose).
- */
- int requiredBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
-
- // Round up the requiredBits to a number of bytes.
- int requiredBytes = (requiredBits + 0x07) >> 3;
-
- /*
- * Write the header byte, which includes the type and
- * requiredBytes - 1.
- */
- out.writeByte(type | ((requiredBytes - 1) << 5));
-
- // Write the value, per se.
- while (requiredBytes > 0) {
- out.writeByte((byte) value);
- value >>= 8;
- requiredBytes--;
- }
- }
-
- /**
- * Writes an unsigned integral to {@code out}.
- */
- public static void writeUnsignedIntegralValue(ByteOutput out, int type, long value) {
- // Figure out how many bits are needed to represent the value.
- int requiredBits = 64 - Long.numberOfLeadingZeros(value);
- if (requiredBits == 0) {
- requiredBits = 1;
- }
-
- // Round up the requiredBits to a number of bytes.
- int requiredBytes = (requiredBits + 0x07) >> 3;
-
- /*
- * Write the header byte, which includes the type and
- * requiredBytes - 1.
- */
- out.writeByte(type | ((requiredBytes - 1) << 5));
-
- // Write the value, per se.
- while (requiredBytes > 0) {
- out.writeByte((byte) value);
- value >>= 8;
- requiredBytes--;
- }
- }
-
- /**
- * Writes a right-zero-extended value to {@code out}.
- */
- public static void writeRightZeroExtendedValue(ByteOutput out, int type, long value) {
- // Figure out how many bits are needed to represent the value.
- int requiredBits = 64 - Long.numberOfTrailingZeros(value);
- if (requiredBits == 0) {
- requiredBits = 1;
- }
-
- // Round up the requiredBits to a number of bytes.
- int requiredBytes = (requiredBits + 0x07) >> 3;
-
- // Scootch the first bits to be written down to the low-order bits.
- value >>= 64 - (requiredBytes * 8);
-
- /*
- * Write the header byte, which includes the type and
- * requiredBytes - 1.
- */
- out.writeByte(type | ((requiredBytes - 1) << 5));
-
- // Write the value, per se.
- while (requiredBytes > 0) {
- out.writeByte((byte) value);
- value >>= 8;
- requiredBytes--;
- }
- }
-
- /**
- * Read a signed integer.
- *
- * @param zwidth byte count minus one
- */
- public static int readSignedInt(ByteInput in, int zwidth) {
- int result = 0;
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
- }
- result >>= (3 - zwidth) * 8;
- return result;
- }
-
- /**
- * Read an unsigned integer.
- *
- * @param zwidth byte count minus one
- * @param fillOnRight true to zero fill on the right; false on the left
- */
- public static int readUnsignedInt(ByteInput in, int zwidth, boolean fillOnRight) {
- int result = 0;
- if (!fillOnRight) {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
- }
- result >>>= (3 - zwidth) * 8;
- } else {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
- }
- }
- return result;
- }
-
- /**
- * Read a signed long.
- *
- * @param zwidth byte count minus one
- */
- public static long readSignedLong(ByteInput in, int zwidth) {
- long result = 0;
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
- }
- result >>= (7 - zwidth) * 8;
- return result;
- }
-
- /**
- * Read an unsigned long.
- *
- * @param zwidth byte count minus one
- * @param fillOnRight true to zero fill on the right; false on the left
- */
- public static long readUnsignedLong(ByteInput in, int zwidth, boolean fillOnRight) {
- long result = 0;
- if (!fillOnRight) {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
- }
- result >>>= (7 - zwidth) * 8;
- } else {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
- }
- }
- return result;
- }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValueReader.java b/dex/src/main/java/com/android/dex/EncodedValueReader.java
deleted file mode 100644
index 6f60538..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValueReader.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.ByteInput;
-
-/**
- * Pull parser for encoded values.
- */
-public final class EncodedValueReader {
- public static final int ENCODED_BYTE = 0x00;
- public static final int ENCODED_SHORT = 0x02;
- public static final int ENCODED_CHAR = 0x03;
- public static final int ENCODED_INT = 0x04;
- public static final int ENCODED_LONG = 0x06;
- public static final int ENCODED_FLOAT = 0x10;
- public static final int ENCODED_DOUBLE = 0x11;
- public static final int ENCODED_STRING = 0x17;
- public static final int ENCODED_TYPE = 0x18;
- public static final int ENCODED_FIELD = 0x19;
- public static final int ENCODED_ENUM = 0x1b;
- public static final int ENCODED_METHOD = 0x1a;
- public static final int ENCODED_ARRAY = 0x1c;
- public static final int ENCODED_ANNOTATION = 0x1d;
- public static final int ENCODED_NULL = 0x1e;
- public static final int ENCODED_BOOLEAN = 0x1f;
-
- /** placeholder type if the type is not yet known */
- private static final int MUST_READ = -1;
-
- protected final ByteInput in;
- private int type = MUST_READ;
- private int annotationType;
- private int arg;
-
- public EncodedValueReader(ByteInput in) {
- this.in = in;
- }
-
- public EncodedValueReader(EncodedValue in) {
- this(in.asByteInput());
- }
-
- /**
- * Creates a new encoded value reader whose only value is the specified
- * known type. This is useful for encoded values without a type prefix,
- * such as class_def_item's encoded_array or annotation_item's
- * encoded_annotation.
- */
- public EncodedValueReader(ByteInput in, int knownType) {
- this.in = in;
- this.type = knownType;
- }
-
- public EncodedValueReader(EncodedValue in, int knownType) {
- this(in.asByteInput(), knownType);
- }
-
- /**
- * Returns the type of the next value to read.
- */
- public int peek() {
- if (type == MUST_READ) {
- int argAndType = in.readByte() & 0xff;
- type = argAndType & 0x1f;
- arg = (argAndType & 0xe0) >> 5;
- }
- return type;
- }
-
- /**
- * Begins reading the elements of an array, returning the array's size. The
- * caller must follow up by calling a read method for each element in the
- * array. For example, this reads a byte array: <pre> {@code
- * int arraySize = readArray();
- * for (int i = 0, i < arraySize; i++) {
- * readByte();
- * }
- * }</pre>
- */
- public int readArray() {
- checkType(ENCODED_ARRAY);
- type = MUST_READ;
- return Leb128.readUnsignedLeb128(in);
- }
-
- /**
- * Begins reading the fields of an annotation, returning the number of
- * fields. The caller must follow up by making alternating calls to {@link
- * #readAnnotationName()} and another read method. For example, this reads
- * an annotation whose fields are all bytes: <pre> {@code
- * int fieldCount = readAnnotation();
- * int annotationType = getAnnotationType();
- * for (int i = 0; i < fieldCount; i++) {
- * readAnnotationName();
- * readByte();
- * }
- * }</pre>
- */
- public int readAnnotation() {
- checkType(ENCODED_ANNOTATION);
- type = MUST_READ;
- annotationType = Leb128.readUnsignedLeb128(in);
- return Leb128.readUnsignedLeb128(in);
- }
-
- /**
- * Returns the type of the annotation just returned by {@link
- * #readAnnotation()}. This method's value is undefined unless the most
- * recent call was to {@link #readAnnotation()}.
- */
- public int getAnnotationType() {
- return annotationType;
- }
-
- public int readAnnotationName() {
- return Leb128.readUnsignedLeb128(in);
- }
-
- public byte readByte() {
- checkType(ENCODED_BYTE);
- type = MUST_READ;
- return (byte) EncodedValueCodec.readSignedInt(in, arg);
- }
-
- public short readShort() {
- checkType(ENCODED_SHORT);
- type = MUST_READ;
- return (short) EncodedValueCodec.readSignedInt(in, arg);
- }
-
- public char readChar() {
- checkType(ENCODED_CHAR);
- type = MUST_READ;
- return (char) EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readInt() {
- checkType(ENCODED_INT);
- type = MUST_READ;
- return EncodedValueCodec.readSignedInt(in, arg);
- }
-
- public long readLong() {
- checkType(ENCODED_LONG);
- type = MUST_READ;
- return EncodedValueCodec.readSignedLong(in, arg);
- }
-
- public float readFloat() {
- checkType(ENCODED_FLOAT);
- type = MUST_READ;
- return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true));
- }
-
- public double readDouble() {
- checkType(ENCODED_DOUBLE);
- type = MUST_READ;
- return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true));
- }
-
- public int readString() {
- checkType(ENCODED_STRING);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readType() {
- checkType(ENCODED_TYPE);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readField() {
- checkType(ENCODED_FIELD);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readEnum() {
- checkType(ENCODED_ENUM);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readMethod() {
- checkType(ENCODED_METHOD);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public void readNull() {
- checkType(ENCODED_NULL);
- type = MUST_READ;
- }
-
- public boolean readBoolean() {
- checkType(ENCODED_BOOLEAN);
- type = MUST_READ;
- return arg != 0;
- }
-
- /**
- * Skips a single value, including its nested values if it is an array or
- * annotation.
- */
- public void skipValue() {
- switch (peek()) {
- case ENCODED_BYTE:
- readByte();
- break;
- case ENCODED_SHORT:
- readShort();
- break;
- case ENCODED_CHAR:
- readChar();
- break;
- case ENCODED_INT:
- readInt();
- break;
- case ENCODED_LONG:
- readLong();
- break;
- case ENCODED_FLOAT:
- readFloat();
- break;
- case ENCODED_DOUBLE:
- readDouble();
- break;
- case ENCODED_STRING:
- readString();
- break;
- case ENCODED_TYPE:
- readType();
- break;
- case ENCODED_FIELD:
- readField();
- break;
- case ENCODED_ENUM:
- readEnum();
- break;
- case ENCODED_METHOD:
- readMethod();
- break;
- case ENCODED_ARRAY:
- for (int i = 0, size = readArray(); i < size; i++) {
- skipValue();
- }
- break;
- case ENCODED_ANNOTATION:
- for (int i = 0, size = readAnnotation(); i < size; i++) {
- readAnnotationName();
- skipValue();
- }
- break;
- case ENCODED_NULL:
- readNull();
- break;
- case ENCODED_BOOLEAN:
- readBoolean();
- break;
- default:
- throw new DexException("Unexpected type: " + Integer.toHexString(type));
- }
- }
-
- private void checkType(int expected) {
- if (peek() != expected) {
- throw new IllegalStateException(
- String.format("Expected %x but was %x", expected, peek()));
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/FieldId.java b/dex/src/main/java/com/android/dex/FieldId.java
deleted file mode 100644
index 2f41708..0000000
--- a/dex/src/main/java/com/android/dex/FieldId.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class FieldId implements Comparable<FieldId> {
- private final Dex dex;
- private final int declaringClassIndex;
- private final int typeIndex;
- private final int nameIndex;
-
- public FieldId(Dex dex, int declaringClassIndex, int typeIndex, int nameIndex) {
- this.dex = dex;
- this.declaringClassIndex = declaringClassIndex;
- this.typeIndex = typeIndex;
- this.nameIndex = nameIndex;
- }
-
- public int getDeclaringClassIndex() {
- return declaringClassIndex;
- }
-
- public int getTypeIndex() {
- return typeIndex;
- }
-
- public int getNameIndex() {
- return nameIndex;
- }
-
- public int compareTo(FieldId other) {
- if (declaringClassIndex != other.declaringClassIndex) {
- return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
- }
- if (nameIndex != other.nameIndex) {
- return Unsigned.compare(nameIndex, other.nameIndex);
- }
- return Unsigned.compare(typeIndex, other.typeIndex); // should always be 0
- }
-
- public void writeTo(Dex.Section out) {
- out.writeUnsignedShort(declaringClassIndex);
- out.writeUnsignedShort(typeIndex);
- out.writeInt(nameIndex);
- }
-
- @Override public String toString() {
- if (dex == null) {
- return declaringClassIndex + " " + typeIndex + " " + nameIndex;
- }
- return dex.typeNames().get(typeIndex) + "." + dex.strings().get(nameIndex);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Leb128.java b/dex/src/main/java/com/android/dex/Leb128.java
deleted file mode 100644
index e4ca500..0000000
--- a/dex/src/main/java/com/android/dex/Leb128.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-
-/**
- * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3
- * section 7.6.
- */
-public final class Leb128 {
- private Leb128() {
- }
-
- /**
- * Gets the number of bytes in the unsigned LEB128 encoding of the
- * given value.
- *
- * @param value the value in question
- * @return its write size, in bytes
- */
- public static int unsignedLeb128Size(int value) {
- // TODO: This could be much cleverer.
-
- int remaining = value >> 7;
- int count = 0;
-
- while (remaining != 0) {
- remaining >>= 7;
- count++;
- }
-
- return count + 1;
- }
-
- /**
- * Reads an signed integer from {@code in}.
- */
- public static int readSignedLeb128(ByteInput in) {
- int result = 0;
- int cur;
- int count = 0;
- int signBits = -1;
-
- do {
- cur = in.readByte() & 0xff;
- result |= (cur & 0x7f) << (count * 7);
- signBits <<= 7;
- count++;
- } while (((cur & 0x80) == 0x80) && count < 5);
-
- if ((cur & 0x80) == 0x80) {
- throw new DexException("invalid LEB128 sequence");
- }
-
- // Sign extend if appropriate
- if (((signBits >> 1) & result) != 0 ) {
- result |= signBits;
- }
-
- return result;
- }
-
- /**
- * Reads an unsigned integer from {@code in}.
- */
- public static int readUnsignedLeb128(ByteInput in) {
- int result = 0;
- int cur;
- int count = 0;
-
- do {
- cur = in.readByte() & 0xff;
- result |= (cur & 0x7f) << (count * 7);
- count++;
- } while (((cur & 0x80) == 0x80) && count < 5);
-
- if ((cur & 0x80) == 0x80) {
- throw new DexException("invalid LEB128 sequence");
- }
-
- return result;
- }
-
- /**
- * Writes {@code value} as an unsigned integer to {@code out}, starting at
- * {@code offset}. Returns the number of bytes written.
- */
- public static void writeUnsignedLeb128(ByteOutput out, int value) {
- int remaining = value >>> 7;
-
- while (remaining != 0) {
- out.writeByte((byte) ((value & 0x7f) | 0x80));
- value = remaining;
- remaining >>>= 7;
- }
-
- out.writeByte((byte) (value & 0x7f));
- }
-
- /**
- * Writes {@code value} as a signed integer to {@code out}, starting at
- * {@code offset}. Returns the number of bytes written.
- */
- public static void writeSignedLeb128(ByteOutput out, int value) {
- int remaining = value >> 7;
- boolean hasMore = true;
- int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
-
- while (hasMore) {
- hasMore = (remaining != end)
- || ((remaining & 1) != ((value >> 6) & 1));
-
- out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));
- value = remaining;
- remaining >>= 7;
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/MethodId.java b/dex/src/main/java/com/android/dex/MethodId.java
deleted file mode 100644
index e518740..0000000
--- a/dex/src/main/java/com/android/dex/MethodId.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class MethodId implements Comparable<MethodId> {
- private final Dex dex;
- private final int declaringClassIndex;
- private final int protoIndex;
- private final int nameIndex;
-
- public MethodId(Dex dex, int declaringClassIndex, int protoIndex, int nameIndex) {
- this.dex = dex;
- this.declaringClassIndex = declaringClassIndex;
- this.protoIndex = protoIndex;
- this.nameIndex = nameIndex;
- }
-
- public int getDeclaringClassIndex() {
- return declaringClassIndex;
- }
-
- public int getProtoIndex() {
- return protoIndex;
- }
-
- public int getNameIndex() {
- return nameIndex;
- }
-
- public int compareTo(MethodId other) {
- if (declaringClassIndex != other.declaringClassIndex) {
- return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
- }
- if (nameIndex != other.nameIndex) {
- return Unsigned.compare(nameIndex, other.nameIndex);
- }
- return Unsigned.compare(protoIndex, other.protoIndex);
- }
-
- public void writeTo(Dex.Section out) {
- out.writeUnsignedShort(declaringClassIndex);
- out.writeUnsignedShort(protoIndex);
- out.writeInt(nameIndex);
- }
-
- @Override public String toString() {
- if (dex == null) {
- return declaringClassIndex + " " + protoIndex + " " + nameIndex;
- }
- return dex.typeNames().get(declaringClassIndex)
- + "." + dex.strings().get(nameIndex)
- + dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset());
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Mutf8.java b/dex/src/main/java/com/android/dex/Mutf8.java
deleted file mode 100644
index c64da33..0000000
--- a/dex/src/main/java/com/android/dex/Mutf8.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import java.io.UTFDataFormatException;
-
-/**
- * Modified UTF-8 as described in the dex file format spec.
- *
- * <p>Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.
- */
-public final class Mutf8 {
- private Mutf8() {}
-
- /**
- * Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is
- * encountered. Returns a new string containing the decoded characters.
- */
- public static String decode(ByteInput in, char[] out) throws UTFDataFormatException {
- int s = 0;
- while (true) {
- char a = (char) (in.readByte() & 0xff);
- if (a == 0) {
- return new String(out, 0, s);
- }
- out[s] = a;
- if (a < '\u0080') {
- s++;
- } else if ((a & 0xe0) == 0xc0) {
- int b = in.readByte() & 0xff;
- if ((b & 0xC0) != 0x80) {
- throw new UTFDataFormatException("bad second byte");
- }
- out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
- } else if ((a & 0xf0) == 0xe0) {
- int b = in.readByte() & 0xff;
- int c = in.readByte() & 0xff;
- if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {
- throw new UTFDataFormatException("bad second or third byte");
- }
- out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
- } else {
- throw new UTFDataFormatException("bad byte");
- }
- }
- }
-
- /**
- * Returns the number of bytes the modified UTF8 representation of 's' would take.
- */
- private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {
- long result = 0;
- final int length = s.length();
- for (int i = 0; i < length; ++i) {
- char ch = s.charAt(i);
- if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
- ++result;
- } else if (ch <= 2047) {
- result += 2;
- } else {
- result += 3;
- }
- if (shortLength && result > 65535) {
- throw new UTFDataFormatException("String more than 65535 UTF bytes long");
- }
- }
- return result;
- }
-
- /**
- * Encodes the modified UTF-8 bytes corresponding to {@code s} into {@code
- * dst}, starting at {@code offset}.
- */
- public static void encode(byte[] dst, int offset, String s) {
- final int length = s.length();
- for (int i = 0; i < length; i++) {
- char ch = s.charAt(i);
- if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
- dst[offset++] = (byte) ch;
- } else if (ch <= 2047) {
- dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));
- dst[offset++] = (byte) (0x80 | (0x3f & ch));
- } else {
- dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));
- dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));
- dst[offset++] = (byte) (0x80 | (0x3f & ch));
- }
- }
- }
-
- /**
- * Returns an array containing the <i>modified UTF-8</i> form of {@code s}.
- */
- public static byte[] encode(String s) throws UTFDataFormatException {
- int utfCount = (int) countBytes(s, true);
- byte[] result = new byte[utfCount];
- encode(result, 0, s);
- return result;
- }
-}
diff --git a/dex/src/main/java/com/android/dex/ProtoId.java b/dex/src/main/java/com/android/dex/ProtoId.java
deleted file mode 100644
index 9d9f484..0000000
--- a/dex/src/main/java/com/android/dex/ProtoId.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class ProtoId implements Comparable<ProtoId> {
- private final Dex dex;
- private final int shortyIndex;
- private final int returnTypeIndex;
- private final int parametersOffset;
-
- public ProtoId(Dex dex, int shortyIndex, int returnTypeIndex, int parametersOffset) {
- this.dex = dex;
- this.shortyIndex = shortyIndex;
- this.returnTypeIndex = returnTypeIndex;
- this.parametersOffset = parametersOffset;
- }
-
- public int compareTo(ProtoId other) {
- if (returnTypeIndex != other.returnTypeIndex) {
- return Unsigned.compare(returnTypeIndex, other.returnTypeIndex);
- }
- return Unsigned.compare(parametersOffset, other.parametersOffset);
- }
-
- public int getShortyIndex() {
- return shortyIndex;
- }
-
- public int getReturnTypeIndex() {
- return returnTypeIndex;
- }
-
- public int getParametersOffset() {
- return parametersOffset;
- }
-
- public void writeTo(Dex.Section out) {
- out.writeInt(shortyIndex);
- out.writeInt(returnTypeIndex);
- out.writeInt(parametersOffset);
- }
-
- @Override public String toString() {
- if (dex == null) {
- return shortyIndex + " " + returnTypeIndex + " " + parametersOffset;
- }
-
- return dex.strings().get(shortyIndex)
- + ": " + dex.typeNames().get(returnTypeIndex)
- + " " + dex.readTypeList(parametersOffset);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/SizeOf.java b/dex/src/main/java/com/android/dex/SizeOf.java
deleted file mode 100644
index 65fab56..0000000
--- a/dex/src/main/java/com/android/dex/SizeOf.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-public final class SizeOf {
- private SizeOf() {}
-
- public static final int UBYTE = 1;
- public static final int USHORT = 2;
- public static final int UINT = 4;
-
- public static final int SIGNATURE = UBYTE * 20;
-
- /**
- * magic ubyte[8]
- * checksum uint
- * signature ubyte[20]
- * file_size uint
- * header_size uint
- * endian_tag uint
- * link_size uint
- * link_off uint
- * map_off uint
- * string_ids_size uint
- * string_ids_off uint
- * type_ids_size uint
- * type_ids_off uint
- * proto_ids_size uint
- * proto_ids_off uint
- * field_ids_size uint
- * field_ids_off uint
- * method_ids_size uint
- * method_ids_off uint
- * class_defs_size uint
- * class_defs_off uint
- * data_size uint
- * data_off uint
- */
- public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70
-
- /**
- * string_data_off uint
- */
- public static final int STRING_ID_ITEM = UINT;
-
- /**
- * descriptor_idx uint
- */
- public static final int TYPE_ID_ITEM = UINT;
-
- /**
- * type_idx ushort
- */
- public static final int TYPE_ITEM = USHORT;
-
- /**
- * shorty_idx uint
- * return_type_idx uint
- * return_type_idx uint
- */
- public static final int PROTO_ID_ITEM = UINT + UINT + UINT;
-
- /**
- * class_idx ushort
- * type_idx/proto_idx ushort
- * name_idx uint
- */
- public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT;
-
- /**
- * class_idx uint
- * access_flags uint
- * superclass_idx uint
- * interfaces_off uint
- * source_file_idx uint
- * annotations_off uint
- * class_data_off uint
- * static_values_off uint
- */
- public static final int CLASS_DEF_ITEM = 8 * UINT;
-
- /**
- * type ushort
- * unused ushort
- * size uint
- * offset uint
- */
- public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT;
-
- /**
- * start_addr uint
- * insn_count ushort
- * handler_off ushort
- */
- public static final int TRY_ITEM = UINT + USHORT + USHORT;
-}
diff --git a/dex/src/main/java/com/android/dex/TableOfContents.java b/dex/src/main/java/com/android/dex/TableOfContents.java
deleted file mode 100644
index b33a749..0000000
--- a/dex/src/main/java/com/android/dex/TableOfContents.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-
-/**
- * The file header and map.
- */
-public final class TableOfContents {
-
- /*
- * TODO: factor out ID constants.
- */
-
- public final Section header = new Section(0x0000);
- public final Section stringIds = new Section(0x0001);
- public final Section typeIds = new Section(0x0002);
- public final Section protoIds = new Section(0x0003);
- public final Section fieldIds = new Section(0x0004);
- public final Section methodIds = new Section(0x0005);
- public final Section classDefs = new Section(0x0006);
- public final Section callSiteIds = new Section(0x0007);
- public final Section methodHandles = new Section(0x0008);
- public final Section mapList = new Section(0x1000);
- public final Section typeLists = new Section(0x1001);
- public final Section annotationSetRefLists = new Section(0x1002);
- public final Section annotationSets = new Section(0x1003);
- public final Section classDatas = new Section(0x2000);
- public final Section codes = new Section(0x2001);
- public final Section stringDatas = new Section(0x2002);
- public final Section debugInfos = new Section(0x2003);
- public final Section annotations = new Section(0x2004);
- public final Section encodedArrays = new Section(0x2005);
- public final Section annotationsDirectories = new Section(0x2006);
- public final Section[] sections = {
- header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList, callSiteIds,
- methodHandles, typeLists, annotationSetRefLists, annotationSets, classDatas, codes,
- stringDatas, debugInfos, annotations, encodedArrays, annotationsDirectories
- };
-
- public int apiLevel;
- public int checksum;
- public byte[] signature;
- public int fileSize;
- public int linkSize;
- public int linkOff;
- public int dataSize;
- public int dataOff;
-
- public TableOfContents() {
- signature = new byte[20];
- }
-
- public void readFrom(Dex dex) throws IOException {
- readHeader(dex.open(0));
- readMap(dex.open(mapList.off));
- computeSizesFromOffsets();
- }
-
- private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {
- byte[] magic = headerIn.readByteArray(8);
-
- if (!DexFormat.isSupportedDexMagic(magic)) {
- String msg =
- String.format("Unexpected magic: [0x%02x, 0x%02x, 0x%02x, 0x%02x, "
- + "0x%02x, 0x%02x, 0x%02x, 0x%02x]",
- magic[0], magic[1], magic[2], magic[3],
- magic[4], magic[5], magic[6], magic[7]);
- throw new DexException(msg);
- }
-
- apiLevel = DexFormat.magicToApi(magic);
- checksum = headerIn.readInt();
- signature = headerIn.readByteArray(20);
- fileSize = headerIn.readInt();
- int headerSize = headerIn.readInt();
- if (headerSize != SizeOf.HEADER_ITEM) {
- throw new DexException("Unexpected header: 0x" + Integer.toHexString(headerSize));
- }
- int endianTag = headerIn.readInt();
- if (endianTag != DexFormat.ENDIAN_TAG) {
- throw new DexException("Unexpected endian tag: 0x" + Integer.toHexString(endianTag));
- }
- linkSize = headerIn.readInt();
- linkOff = headerIn.readInt();
- mapList.off = headerIn.readInt();
- if (mapList.off == 0) {
- throw new DexException("Cannot merge dex files that do not contain a map");
- }
- stringIds.size = headerIn.readInt();
- stringIds.off = headerIn.readInt();
- typeIds.size = headerIn.readInt();
- typeIds.off = headerIn.readInt();
- protoIds.size = headerIn.readInt();
- protoIds.off = headerIn.readInt();
- fieldIds.size = headerIn.readInt();
- fieldIds.off = headerIn.readInt();
- methodIds.size = headerIn.readInt();
- methodIds.off = headerIn.readInt();
- classDefs.size = headerIn.readInt();
- classDefs.off = headerIn.readInt();
- dataSize = headerIn.readInt();
- dataOff = headerIn.readInt();
- }
-
- private void readMap(Dex.Section in) throws IOException {
- int mapSize = in.readInt();
- Section previous = null;
- for (int i = 0; i < mapSize; i++) {
- short type = in.readShort();
- in.readShort(); // unused
- Section section = getSection(type);
- int size = in.readInt();
- int offset = in.readInt();
-
- if ((section.size != 0 && section.size != size)
- || (section.off != -1 && section.off != offset)) {
- throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
- }
-
- section.size = size;
- section.off = offset;
-
- if (previous != null && previous.off > section.off) {
- throw new DexException("Map is unsorted at " + previous + ", " + section);
- }
-
- previous = section;
- }
- Arrays.sort(sections);
- }
-
- public void computeSizesFromOffsets() {
- int end = dataOff + dataSize;
- for (int i = sections.length - 1; i >= 0; i--) {
- Section section = sections[i];
- if (section.off == -1) {
- continue;
- }
- if (section.off > end) {
- throw new DexException("Map is unsorted at " + section);
- }
- section.byteCount = end - section.off;
- end = section.off;
- }
- }
-
- private Section getSection(short type) {
- for (Section section : sections) {
- if (section.type == type) {
- return section;
- }
- }
- throw new IllegalArgumentException("No such map item: " + type);
- }
-
- public void writeHeader(Dex.Section out, int api) throws IOException {
- out.write(DexFormat.apiToMagic(api).getBytes("UTF-8"));
- out.writeInt(checksum);
- out.write(signature);
- out.writeInt(fileSize);
- out.writeInt(SizeOf.HEADER_ITEM);
- out.writeInt(DexFormat.ENDIAN_TAG);
- out.writeInt(linkSize);
- out.writeInt(linkOff);
- out.writeInt(mapList.off);
- out.writeInt(stringIds.size);
- out.writeInt(stringIds.off);
- out.writeInt(typeIds.size);
- out.writeInt(typeIds.off);
- out.writeInt(protoIds.size);
- out.writeInt(protoIds.off);
- out.writeInt(fieldIds.size);
- out.writeInt(fieldIds.off);
- out.writeInt(methodIds.size);
- out.writeInt(methodIds.off);
- out.writeInt(classDefs.size);
- out.writeInt(classDefs.off);
- out.writeInt(dataSize);
- out.writeInt(dataOff);
- }
-
- public void writeMap(Dex.Section out) throws IOException {
- int count = 0;
- for (Section section : sections) {
- if (section.exists()) {
- count++;
- }
- }
-
- out.writeInt(count);
- for (Section section : sections) {
- if (section.exists()) {
- out.writeShort(section.type);
- out.writeShort((short) 0);
- out.writeInt(section.size);
- out.writeInt(section.off);
- }
- }
- }
-
- public static class Section implements Comparable<Section> {
- public final short type;
- public int size = 0;
- public int off = -1;
- public int byteCount = 0;
-
- public Section(int type) {
- this.type = (short) type;
- }
-
- public boolean exists() {
- return size > 0;
- }
-
- public int compareTo(Section section) {
- if (off != section.off) {
- return off < section.off ? -1 : 1;
- }
- return 0;
- }
-
- @Override public String toString() {
- return String.format("Section[type=%#x,off=%#x,size=%#x]", type, off, size);
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/TypeList.java b/dex/src/main/java/com/android/dex/TypeList.java
deleted file mode 100644
index 123e82c..0000000
--- a/dex/src/main/java/com/android/dex/TypeList.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class TypeList implements Comparable<TypeList> {
-
- public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY);
-
- private final Dex dex;
- private final short[] types;
-
- public TypeList(Dex dex, short[] types) {
- this.dex = dex;
- this.types = types;
- }
-
- public short[] getTypes() {
- return types;
- }
-
- @Override public int compareTo(TypeList other) {
- for (int i = 0; i < types.length && i < other.types.length; i++) {
- if (types[i] != other.types[i]) {
- return Unsigned.compare(types[i], other.types[i]);
- }
- }
- return Unsigned.compare(types.length, other.types.length);
- }
-
- @Override public String toString() {
- StringBuilder result = new StringBuilder();
- result.append("(");
- for (int i = 0, typesLength = types.length; i < typesLength; i++) {
- result.append(dex != null ? dex.typeNames().get(types[i]) : types[i]);
- }
- result.append(")");
- return result.toString();
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java b/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java
deleted file mode 100644
index 889a936..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex.util;
-
-public final class ByteArrayByteInput implements ByteInput {
-
- private final byte[] bytes;
- private int position;
-
- public ByteArrayByteInput(byte... bytes) {
- this.bytes = bytes;
- }
-
- @Override public byte readByte() {
- return bytes[position++];
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteInput.java b/dex/src/main/java/com/android/dex/util/ByteInput.java
deleted file mode 100644
index f1a7196..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteInput.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex.util;
-
-/**
- * A byte source.
- */
-public interface ByteInput {
-
- /**
- * Returns a byte.
- *
- * @throws IndexOutOfBoundsException if all bytes have been read.
- */
- byte readByte();
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteOutput.java b/dex/src/main/java/com/android/dex/util/ByteOutput.java
deleted file mode 100644
index eb77040..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteOutput.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex.util;
-
-/**
- * A byte sink.
- */
-public interface ByteOutput {
-
- /**
- * Writes a byte.
- *
- * @throws IndexOutOfBoundsException if all bytes have been written.
- */
- void writeByte(int i);
-}
diff --git a/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java b/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java
deleted file mode 100644
index 5dfd954..0000000
--- a/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex.util;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * Exception which carries around structured context.
- */
-public class ExceptionWithContext extends RuntimeException {
- /** {@code non-null;} human-oriented context of the exception */
- private StringBuffer context;
-
- /**
- * Augments the given exception with the given context, and return the
- * result. The result is either the given exception if it was an
- * {@link ExceptionWithContext}, or a newly-constructed exception if it
- * was not.
- *
- * @param ex {@code non-null;} the exception to augment
- * @param str {@code non-null;} context to add
- * @return {@code non-null;} an appropriate instance
- */
- public static ExceptionWithContext withContext(Throwable ex, String str) {
- ExceptionWithContext ewc;
-
- if (ex instanceof ExceptionWithContext) {
- ewc = (ExceptionWithContext) ex;
- } else {
- ewc = new ExceptionWithContext(ex);
- }
-
- ewc.addContext(str);
- return ewc;
- }
-
- /**
- * Constructs an instance.
- *
- * @param message human-oriented message
- */
- public ExceptionWithContext(String message) {
- this(message, null);
- }
-
- /**
- * Constructs an instance.
- *
- * @param cause {@code null-ok;} exception that caused this one
- */
- public ExceptionWithContext(Throwable cause) {
- this(null, cause);
- }
-
- /**
- * Constructs an instance.
- *
- * @param message human-oriented message
- * @param cause {@code null-ok;} exception that caused this one
- */
- public ExceptionWithContext(String message, Throwable cause) {
- super((message != null) ? message :
- (cause != null) ? cause.getMessage() : null,
- cause);
-
- if (cause instanceof ExceptionWithContext) {
- String ctx = ((ExceptionWithContext) cause).context.toString();
- context = new StringBuffer(ctx.length() + 200);
- context.append(ctx);
- } else {
- context = new StringBuffer(200);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public void printStackTrace(PrintStream out) {
- super.printStackTrace(out);
- out.println(context);
- }
-
- /** {@inheritDoc} */
- @Override
- public void printStackTrace(PrintWriter out) {
- super.printStackTrace(out);
- out.println(context);
- }
-
- /**
- * Adds a line of context to this instance.
- *
- * @param str {@code non-null;} new context
- */
- public void addContext(String str) {
- if (str == null) {
- throw new NullPointerException("str == null");
- }
-
- context.append(str);
- if (!str.endsWith("\n")) {
- context.append('\n');
- }
- }
-
- /**
- * Gets the context.
- *
- * @return {@code non-null;} the context
- */
- public String getContext() {
- return context.toString();
- }
-
- /**
- * Prints the message and context.
- *
- * @param out {@code non-null;} where to print to
- */
- public void printContext(PrintStream out) {
- out.println(getMessage());
- out.print(context);
- }
-
- /**
- * Prints the message and context.
- *
- * @param out {@code non-null;} where to print to
- */
- public void printContext(PrintWriter out) {
- out.println(getMessage());
- out.print(context);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/FileUtils.java b/dex/src/main/java/com/android/dex/util/FileUtils.java
deleted file mode 100644
index 4cea95c..0000000
--- a/dex/src/main/java/com/android/dex/util/FileUtils.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * File I/O utilities.
- */
-public final class FileUtils {
- private FileUtils() {
- }
-
- /**
- * Reads the named file, translating {@link IOException} to a
- * {@link RuntimeException} of some sort.
- *
- * @param fileName {@code non-null;} name of the file to read
- * @return {@code non-null;} contents of the file
- */
- public static byte[] readFile(String fileName) {
- File file = new File(fileName);
- return readFile(file);
- }
-
- /**
- * Reads the given file, translating {@link IOException} to a
- * {@link RuntimeException} of some sort.
- *
- * @param file {@code non-null;} the file to read
- * @return {@code non-null;} contents of the file
- */
- public static byte[] readFile(File file) {
- if (!file.exists()) {
- throw new RuntimeException(file + ": file not found");
- }
-
- if (!file.isFile()) {
- throw new RuntimeException(file + ": not a file");
- }
-
- if (!file.canRead()) {
- throw new RuntimeException(file + ": file not readable");
- }
-
- long longLength = file.length();
- int length = (int) longLength;
- if (length != longLength) {
- throw new RuntimeException(file + ": file too long");
- }
-
- byte[] result = new byte[length];
-
- try {
- FileInputStream in = new FileInputStream(file);
- int at = 0;
- while (length > 0) {
- int amt = in.read(result, at, length);
- if (amt == -1) {
- throw new RuntimeException(file + ": unexpected EOF");
- }
- at += amt;
- length -= amt;
- }
- in.close();
- } catch (IOException ex) {
- throw new RuntimeException(file + ": trouble reading", ex);
- }
-
- return result;
- }
-
- /**
- * Returns true if {@code fileName} names a .zip, .jar, or .apk.
- */
- public static boolean hasArchiveSuffix(String fileName) {
- return fileName.endsWith(".zip")
- || fileName.endsWith(".jar")
- || fileName.endsWith(".apk");
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/Unsigned.java b/dex/src/main/java/com/android/dex/util/Unsigned.java
deleted file mode 100644
index cb50d0a..0000000
--- a/dex/src/main/java/com/android/dex/util/Unsigned.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex.util;
-
-/**
- * Unsigned arithmetic over Java's signed types.
- */
-public final class Unsigned {
- private Unsigned() {}
-
- public static int compare(short ushortA, short ushortB) {
- if (ushortA == ushortB) {
- return 0;
- }
- int a = ushortA & 0xFFFF;
- int b = ushortB & 0xFFFF;
- return a < b ? -1 : 1;
- }
-
- public static int compare(int uintA, int uintB) {
- if (uintA == uintB) {
- return 0;
- }
- long a = uintA & 0xFFFFFFFFL;
- long b = uintB & 0xFFFFFFFFL;
- return a < b ? -1 : 1;
- }
-}
diff --git a/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java b/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java
deleted file mode 100644
index a4ca376..0000000
--- a/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dex;
-
-import com.android.dex.util.ByteArrayByteInput;
-import junit.framework.TestCase;
-
-public final class EncodedValueReaderTest extends TestCase {
-
- public void testReadByte() {
- assertEquals((byte) 0x80, readerOf(0, 0x80).readByte());
- assertEquals((byte) 0xff, readerOf(0, 0xff).readByte());
- assertEquals((byte) 0x00, readerOf(0, 0x00).readByte());
- assertEquals((byte) 0x01, readerOf(0, 0x01).readByte());
- assertEquals((byte) 0x7f, readerOf(0, 0x7f).readByte());
- }
-
- public void testReadShort() {
- assertEquals((short) 0x8000, readerOf(34, 0x00, 0x80).readShort());
- assertEquals((short) 0, readerOf( 2, 0x00).readShort());
- assertEquals((short) 0xab, readerOf(34, 0xab, 0x00).readShort());
- assertEquals((short) 0xabcd, readerOf(34, 0xcd, 0xab).readShort());
- assertEquals((short) 0x7FFF, readerOf(34, 0xff, 0x7f).readShort());
- }
-
- public void testReadInt() {
- assertEquals(0x80000000, readerOf(100, 0x00, 0x00, 0x00, 0x80).readInt());
- assertEquals( 0x00, readerOf( 4, 0x00).readInt());
- assertEquals( 0xab, readerOf( 36, 0xab, 0x00).readInt());
- assertEquals( 0xabcd, readerOf( 68, 0xcd, 0xab, 0x00).readInt());
- assertEquals( 0xabcdef, readerOf(100, 0xef, 0xcd, 0xab, 0x00).readInt());
- assertEquals(0xabcdef01, readerOf(100, 0x01, 0xef, 0xcd, 0xab).readInt());
- assertEquals(0x7fffffff, readerOf(100, 0xff, 0xff, 0xff, 127).readInt());
- }
-
- public void testReadLong() {
- assertEquals(0x8000000000000000L, readerOf( -26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80).readLong());
- assertEquals( 0x00L, readerOf( 6, 0x00).readLong());
- assertEquals( 0xabL, readerOf( 38, 0xab, 0x00).readLong());
- assertEquals( 0xabcdL, readerOf( 70, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdefL, readerOf( 102, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef01L, readerOf(-122, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef0123L, readerOf( -90, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef012345L, readerOf( -58, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef01234567L, readerOf( -26, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals(0xabcdef0123456789L, readerOf( -26, 0x89, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab).readLong());
- assertEquals(0x7fffffffffffffffL, readerOf( -26, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f).readLong());
- }
-
- public void testReadFloat() {
- assertEquals(Float.NEGATIVE_INFINITY, readerOf(48, -128, -1).readFloat());
- assertEquals(Float.POSITIVE_INFINITY, readerOf(48, -128, 127).readFloat());
- assertEquals(Float.NaN, readerOf(48, -64, 127).readFloat());
- assertEquals(-0.0f, readerOf(16, -128).readFloat());
- assertEquals(0.0f, readerOf(16, 0).readFloat());
- assertEquals(0.5f, readerOf(16, 63).readFloat());
- assertEquals(1f, readerOf(48, -128, 63).readFloat());
- assertEquals(1.0E06f, readerOf(80, 36, 116, 73).readFloat());
- assertEquals(1.0E12f, readerOf(112, -91, -44, 104, 83).readFloat());
- }
-
- public void testReadDouble() {
- assertEquals(Double.NEGATIVE_INFINITY, readerOf(49, -16, -1).readDouble());
- assertEquals(Double.POSITIVE_INFINITY, readerOf(49, -16, 127).readDouble());
- assertEquals(Double.NaN, readerOf(49, -8, 127).readDouble());
- assertEquals(-0.0, readerOf(17, -128).readDouble());
- assertEquals(0.0, readerOf(17, 0).readDouble());
- assertEquals(0.5, readerOf(49, -32, 63).readDouble());
- assertEquals(1.0, readerOf(49, -16, 63).readDouble());
- assertEquals(1.0E06, readerOf(113, -128, -124, 46, 65).readDouble());
- assertEquals(1.0E12, readerOf(-111, -94, -108, 26, 109, 66).readDouble());
- assertEquals(1.0E24, readerOf(-15, -76, -99, -39, 121, 67, 120, -22, 68).readDouble());
- }
-
- public void testReadChar() {
- assertEquals('\u0000', readerOf( 3, 0x00).readChar());
- assertEquals('\u00ab', readerOf( 3, 0xab).readChar());
- assertEquals('\uabcd', readerOf(35, 0xcd, 0xab).readChar());
- assertEquals('\uffff', readerOf(35, 0xff, 0xff).readChar());
- }
-
- public void testReadBoolean() {
- assertEquals(true, readerOf(63).readBoolean());
- assertEquals(false, readerOf(31).readBoolean());
- }
-
- public void testReadNull() {
- readerOf(30).readNull();
- }
-
- public void testReadReference() {
- assertEquals( 0xab, readerOf(0x17, 0xab).readString());
- assertEquals( 0xabcd, readerOf(0x37, 0xcd, 0xab).readString());
- assertEquals( 0xabcdef, readerOf(0x57, 0xef, 0xcd, 0xab).readString());
- assertEquals(0xabcdef01, readerOf(0x77, 0x01, 0xef, 0xcd, 0xab).readString());
- }
-
- public void testReadWrongType() {
- try {
- readerOf(0x17, 0xab).readField();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- private EncodedValueReader readerOf(int... bytes) {
- byte[] data = new byte[bytes.length];
- for (int i = 0; i < bytes.length; i++) {
- data[i] = (byte) bytes[i];
- }
- return new EncodedValueReader(new ByteArrayByteInput(data));
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
index fc99502..9d6c950 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
@@ -17,10 +17,12 @@
package org.apache.harmony.tests.java.net;
+import libcore.io.Libcore;
import libcore.junit.junit3.TestCaseWithRules;
import libcore.junit.util.ResourceLeakageDetector;
import org.junit.Rule;
import org.junit.rules.TestRule;
+
import tests.support.Support_Configuration;
import java.io.IOException;
import java.io.InputStream;
@@ -42,6 +44,9 @@
import java.util.Locale;
import java.util.Properties;
+import static android.system.OsConstants.F_GETFL;
+import static android.system.OsConstants.O_NONBLOCK;
+
public class ServerSocketTest extends TestCaseWithRules {
@Rule
public TestRule guardRule = ResourceLeakageDetector.getRule();
@@ -174,12 +179,16 @@
/**
* java.net.ServerSocket#accept()
*/
- public void test_accept() throws IOException {
+ public void test_accept() throws Exception {
s = new ServerSocket(0);
try {
s.setSoTimeout(5000);
startClient(s.getLocalPort());
sconn = s.accept();
+
+ // The new socket should not be blocking.
+ assertEquals(0, Libcore.os.fcntlVoid(sconn.getFileDescriptor$(), F_GETFL) & O_NONBLOCK);
+
int localPort1 = s.getLocalPort();
int localPort2 = sconn.getLocalPort();
sconn.close();
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
index 94ad327..b4cf99b 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
@@ -172,11 +172,6 @@
assertTrue("Returned incorrect country: "
+ testLocale.getDisplayCountry(), testLocale
.getDisplayCountry().equals("Canada"));
-
- // Regression for Harmony-1146
- Locale l_countryCD = new Locale("", "CD");
- assertEquals("Congo (DRC)",
- l_countryCD.getDisplayCountry());
}
public void test_getDisplayCountryLjava_util_Locale() {
diff --git a/libart/src/main/java/dalvik/system/ClassExt.java b/libart/src/main/java/dalvik/system/ClassExt.java
index 772bd2e..9c9fa7a 100644
--- a/libart/src/main/java/dalvik/system/ClassExt.java
+++ b/libart/src/main/java/dalvik/system/ClassExt.java
@@ -48,7 +48,8 @@
private Object obsoleteMethods;
/**
- * If set, the bytes of the original dex-file associated with the related class.
+ * If set, the bytes, native pointer (as a java.lang.Long), or DexCache of the original dex-file
+ * associated with the related class.
*
* In this instance 'original' means either (1) the dex-file loaded for this class when it was
* first loaded after all non-retransformation capable transformations had been performed but
@@ -59,7 +60,7 @@
*
* This field is a logical part of the 'Class' type.
*/
- private byte[] originalDexFile;
+ private Object originalDexFile;
/**
* If class verify fails, we must return same error on subsequent tries. We may store either
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index 7e5bdff..864196d 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -33,17 +33,13 @@
package java.lang;
import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
/**
* A dex cache holds resolved copies of strings, fields, methods, and classes from the dexfile.
*/
final class DexCache {
- /** Lazily initialized dex file wrapper. Volatile to avoid double-check locking issues. */
- private volatile Dex dex;
-
/** The location of the associated dex file. */
- String location;
+ private String location;
/** Holds C pointer to dexFile. */
private long dexFile;
@@ -116,29 +112,5 @@
// Only created by the VM.
private DexCache() {}
-
- Dex getDex() {
- Dex result = dex;
- if (result == null) {
- synchronized (this) {
- result = dex;
- if (result == null) {
- dex = result = getDexNative();
- }
- }
- }
- return result;
- }
-
- @FastNative
- native Class<?> getResolvedType(int typeIndex);
- @FastNative
- native String getResolvedString(int stringIndex);
- @FastNative
- native void setResolvedType(int typeIndex, Class<?> type);
- @FastNative
- native void setResolvedString(int stringIndex, String string);
- @FastNative
- private native Dex getDexNative();
}
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index cae8083..7db7f75 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -63,6 +63,25 @@
/** @hide */ public static void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.bind(fd, address); }
/**
+ * See <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+ *
+ * @hide
+ */
+ public static StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+ return Libcore.os.capget(hdr);
+ }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/capset.2.html">capset(2)</a>.
+ *
+ * @hide
+ */
+ public static void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+ throws ErrnoException {
+ Libcore.os.capset(hdr, data);
+ }
+
+ /**
* See <a href="http://man7.org/linux/man-pages/man2/chmod.2.html">chmod(2)</a>.
*/
public static void chmod(String path, int mode) throws ErrnoException { Libcore.os.chmod(path, mode); }
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 10ea52f..adad301 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -24,6 +24,20 @@
}
/**
+ * Returns the index of the element in the cap_user_data array that this capability is stored
+ * in.
+ * @hide
+ */
+ public static int CAP_TO_INDEX(int x) { return x >>> 5; }
+
+ /**
+ * Returns the mask for the given capability. This is relative to the capability's cap_user_data
+ * element, the index of which can be retrieved with CAP_TO_INDEX.
+ * @hide
+ */
+ public static int CAP_TO_MASK(int x) { return 1 << (x & 31); }
+
+ /**
* Tests whether the given mode is a block device.
*/
public static boolean S_ISBLK(int mode) { return (mode & S_IFMT) == S_IFBLK; }
@@ -320,6 +334,7 @@
/** @hide */ public static final int IP_RECVTOS = placeholder();
public static final int IP_TOS = placeholder();
public static final int IP_TTL = placeholder();
+ /** @hide */ public static final int _LINUX_CAPABILITY_VERSION_3 = placeholder();
public static final int MAP_FIXED = placeholder();
/** @hide */ public static final int MAP_POPULATE = placeholder();
public static final int MAP_PRIVATE = placeholder();
@@ -372,6 +387,8 @@
public static final int POLLRDNORM = placeholder();
public static final int POLLWRBAND = placeholder();
public static final int POLLWRNORM = placeholder();
+ /** @hide */ public static final int PR_CAP_AMBIENT = placeholder();
+ /** @hide */ public static final int PR_CAP_AMBIENT_RAISE = placeholder();
public static final int PR_GET_DUMPABLE = placeholder();
public static final int PR_SET_DUMPABLE = placeholder();
public static final int PR_SET_NO_NEW_PRIVS = placeholder();
diff --git a/luni/src/main/java/android/system/StructCapUserData.java b/luni/src/main/java/android/system/StructCapUserData.java
new file mode 100644
index 0000000..af63caf
--- /dev/null
+++ b/luni/src/main/java/android/system/StructCapUserData.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to Linux' __user_cap_data_struct for capget and capset.
+ *
+ * @hide
+ */
+public final class StructCapUserData {
+ /** Effective capability mask. */
+ public final int effective; /* __u32 */
+
+ /** Permitted capability mask. */
+ public final int permitted; /* __u32 */
+
+ /** Inheritable capability mask. */
+ public final int inheritable; /* __u32 */
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructCapUserData(int effective, int permitted, int inheritable) {
+ this.effective = effective;
+ this.permitted = permitted;
+ this.inheritable = inheritable;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructCapUserHeader.java b/luni/src/main/java/android/system/StructCapUserHeader.java
new file mode 100644
index 0000000..abbb395
--- /dev/null
+++ b/luni/src/main/java/android/system/StructCapUserHeader.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to Linux' __user_cap_header_struct for capget and capset.
+ *
+ * @hide
+ */
+public final class StructCapUserHeader {
+ /**
+ * Version of the header. Note this is not final as capget() may mutate the field when an
+ * invalid version is provided. See
+ * <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+ */
+ public int version; /* __u32 */
+
+ /** Pid of the header. The pid a call applies to. */
+ public final int pid;
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructCapUserHeader(int version, int pid) {
+ this.version = version;
+ this.pid = pid;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index ac805e8..55d4d82 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -19,6 +19,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.system.StructFlock;
import android.system.StructGroupReq;
import android.system.StructGroupSourceReq;
@@ -56,6 +58,14 @@
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return os.android_getaddrinfo(node, hints, netId); }
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.bind(fd, address); }
+ @Override
+ public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+ return os.capget(hdr);
+ }
+ @Override
+ public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException {
+ os.capset(hdr, data);
+ }
public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
public void chown(String path, int uid, int gid) throws ErrnoException { os.chown(path, uid, gid); }
public void close(FileDescriptor fd) throws ErrnoException { os.close(fd); }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index 0c34d5e..7adae8b 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -34,6 +34,7 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
+import java.net.NoRouteToHostException;
import java.net.PortUnreachableException;
import java.net.SocketAddress;
import java.net.SocketException;
@@ -128,6 +129,12 @@
try {
connectErrno(fd, inetAddress, port, timeoutMs);
} catch (ErrnoException errnoException) {
+ if (errnoException.errno == EHOSTUNREACH) {
+ throw new NoRouteToHostException("Host unreachable");
+ }
+ if (errnoException.errno == EADDRNOTAVAIL) {
+ throw new NoRouteToHostException("Address not available");
+ }
throw new ConnectException(connectDetail(fd, inetAddress, port, timeoutMs,
errnoException), errnoException);
} catch (SocketException ex) {
@@ -141,7 +148,7 @@
private static void connectErrno(FileDescriptor fd, InetAddress inetAddress, int port, int timeoutMs) throws ErrnoException, IOException {
// With no timeout, just call connect(2) directly.
- if (timeoutMs == 0) {
+ if (timeoutMs <= 0) {
Libcore.os.connect(fd, inetAddress, port);
return;
}
diff --git a/luni/src/main/java/libcore/io/Libcore.java b/luni/src/main/java/libcore/io/Libcore.java
index 478ed6d..cbc5a55 100644
--- a/luni/src/main/java/libcore/io/Libcore.java
+++ b/luni/src/main/java/libcore/io/Libcore.java
@@ -24,7 +24,7 @@
* unless it has a strong reason to bypass the helpful checks/guards that it
* provides.
*/
- public static Os rawOs = new Posix();
+ public static Os rawOs = new Linux();
/**
* Access to syscalls with helpful checks/guards.
diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Linux.java
similarity index 97%
rename from luni/src/main/java/libcore/io/Posix.java
rename to luni/src/main/java/libcore/io/Linux.java
index 1a74678..09adb09 100644
--- a/luni/src/main/java/libcore/io/Posix.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -19,6 +19,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.system.StructFlock;
import android.system.StructGroupReq;
import android.system.StructGroupSourceReq;
@@ -42,14 +44,19 @@
import java.nio.ByteBuffer;
import java.nio.NioUtils;
-public final class Posix implements Os {
- Posix() { }
+public final class Linux implements Os {
+ Linux() { }
public native FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException;
public native boolean access(String path, int mode) throws ErrnoException;
public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public native void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
+ @Override
+ public native StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
+ @Override
+ public native void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+ throws ErrnoException;
public native void chmod(String path, int mode) throws ErrnoException;
public native void chown(String path, int uid, int gid) throws ErrnoException;
public native void close(FileDescriptor fd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 41b034b..20a84bd 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -19,6 +19,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.system.StructFlock;
import android.system.StructGroupReq;
import android.system.StructGroupSourceReq;
@@ -47,6 +49,8 @@
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
+ public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
+ public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException;
public void chmod(String path, int mode) throws ErrnoException;
public void chown(String path, int uid, int gid) throws ErrnoException;
public void close(FileDescriptor fd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/util/TimeZoneDataFiles.java b/luni/src/main/java/libcore/util/TimeZoneDataFiles.java
new file mode 100644
index 0000000..8361339
--- /dev/null
+++ b/luni/src/main/java/libcore/util/TimeZoneDataFiles.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+/**
+ * Utility methods associated with finding updateable time zone data files.
+ */
+public final class TimeZoneDataFiles {
+
+ private static final String ANDROID_ROOT_ENV = "ANDROID_ROOT";
+ private static final String ANDROID_DATA_ENV = "ANDROID_DATA";
+
+ private TimeZoneDataFiles() {}
+
+ // VisibleForTesting
+ public static String[] getTimeZoneFilePaths(String fileName) {
+ return new String[] {
+ getDataTimeZoneFile(fileName),
+ getSystemTimeZoneFile(fileName)
+ };
+ }
+
+ private static String getDataTimeZoneFile(String fileName) {
+ return System.getenv(ANDROID_DATA_ENV) + "/misc/zoneinfo/current/" + fileName;
+ }
+
+ // VisibleForTesting
+ public static String getSystemTimeZoneFile(String fileName) {
+ return System.getenv(ANDROID_ROOT_ENV) + "/usr/share/zoneinfo/" + fileName;
+ }
+
+ public static String generateIcuDataPath() {
+ StringBuilder icuDataPathBuilder = new StringBuilder();
+ // ICU should first look in ANDROID_DATA. This is used for (optional) timezone data.
+ String dataIcuDataPath = getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu");
+ if (dataIcuDataPath != null) {
+ icuDataPathBuilder.append(dataIcuDataPath);
+ }
+
+ // ICU should always look in ANDROID_ROOT.
+ String systemIcuDataPath = getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu");
+ if (systemIcuDataPath != null) {
+ if (icuDataPathBuilder.length() > 0) {
+ icuDataPathBuilder.append(":");
+ }
+ icuDataPathBuilder.append(systemIcuDataPath);
+ }
+ return icuDataPathBuilder.toString();
+ }
+
+ /**
+ * Creates a path by combining the value of an environment variable with a relative path.
+ * Returns {@code null} if the environment variable is not set.
+ */
+ private static String getEnvironmentPath(String environmentVariable, String path) {
+ String variable = System.getenv(environmentVariable);
+ if (variable == null) {
+ return null;
+ }
+ return variable + path;
+ }
+}
diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java
index d9ff323..acb9c12 100644
--- a/luni/src/main/java/libcore/util/ZoneInfoDB.java
+++ b/luni/src/main/java/libcore/util/ZoneInfoDB.java
@@ -37,9 +37,12 @@
* @hide - used to implement TimeZone
*/
public final class ZoneInfoDB {
- private static final TzData DATA = TzData.loadTzDataWithFallback(
- System.getenv("ANDROID_DATA") + "/misc/zoneinfo/current/tzdata",
- System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata");
+
+ // VisibleForTesting
+ public static final String TZDATA_FILE = "tzdata";
+
+ private static final TzData DATA =
+ TzData.loadTzDataWithFallback(TimeZoneDataFiles.getTimeZoneFilePaths(TZDATA_FILE));
public static class TzData {
@@ -114,7 +117,7 @@
// We didn't find any usable tzdata on disk, so let's just hard-code knowledge of "GMT".
// This is actually implemented in TimeZone itself, so if this is the only time zone
// we report, we won't be asked any more questions.
- System.logE("Couldn't find any tzdata!");
+ System.logE("Couldn't find any " + TZDATA_FILE + " file!");
return TzData.createFallback();
}
@@ -183,7 +186,7 @@
// Something's wrong with the file.
// Log the problem and return false so we try the next choice.
- System.logE("tzdata file \"" + path + "\" was present but invalid!", ex);
+ System.logE(TZDATA_FILE + " file \"" + path + "\" was present but invalid!", ex);
return false;
}
}
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 3c244ef..f642211 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -44,8 +44,8 @@
REGISTER(register_libcore_icu_NativeConverter);
REGISTER(register_libcore_icu_TimeZoneNames);
REGISTER(register_libcore_io_AsynchronousCloseMonitor);
+ REGISTER(register_libcore_io_Linux);
REGISTER(register_libcore_io_Memory);
- REGISTER(register_libcore_io_Posix);
REGISTER(register_libcore_util_NativeAllocationRegistry);
REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget);
REGISTER(register_org_apache_harmony_xml_ExpatParser);
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 3cb3ee9..3ae4af6 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -342,6 +342,9 @@
initConstant(env, c, "IP_RECVTOS", IP_RECVTOS);
initConstant(env, c, "IP_TOS", IP_TOS);
initConstant(env, c, "IP_TTL", IP_TTL);
+#if defined(_LINUX_CAPABILITY_VERSION_3)
+ initConstant(env, c, "_LINUX_CAPABILITY_VERSION_3", _LINUX_CAPABILITY_VERSION_3);
+#endif
initConstant(env, c, "MAP_FIXED", MAP_FIXED);
initConstant(env, c, "MAP_POPULATE", MAP_POPULATE);
initConstant(env, c, "MAP_PRIVATE", MAP_PRIVATE);
@@ -406,6 +409,12 @@
initConstant(env, c, "POLLRDNORM", POLLRDNORM);
initConstant(env, c, "POLLWRBAND", POLLWRBAND);
initConstant(env, c, "POLLWRNORM", POLLWRNORM);
+#if defined(PR_CAP_AMBIENT)
+ initConstant(env, c, "PR_CAP_AMBIENT", PR_CAP_AMBIENT);
+#endif
+#if defined(PR_CAP_AMBIENT_RAISE)
+ initConstant(env, c, "PR_CAP_AMBIENT_RAISE", PR_CAP_AMBIENT_RAISE);
+#endif
#if defined(PR_GET_DUMPABLE)
initConstant(env, c, "PR_GET_DUMPABLE", PR_GET_DUMPABLE);
#endif
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp
index 46594c6..0e9a2bc 100644
--- a/luni/src/main/native/libcore_icu_ICU.cpp
+++ b/luni/src/main/native/libcore_icu_ICU.cpp
@@ -57,6 +57,7 @@
#include "unicode/timezone.h"
#include "unicode/ubrk.h"
#include "unicode/ucal.h"
+#include "unicode/ucasemap.h"
#include "unicode/uclean.h"
#include "unicode/ucol.h"
#include "unicode/ucurr.h"
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Linux.cpp
similarity index 77%
rename from luni/src/main/native/libcore_io_Posix.cpp
rename to luni/src/main/native/libcore_io_Linux.cpp
index d150052..1e2f3a5 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "Posix"
+#define LOG_TAG "Linux"
#include <arpa/inet.h>
#include <errno.h>
@@ -29,6 +29,7 @@
#include <pwd.h>
#include <signal.h>
#include <stdlib.h>
+#include <sys/capability.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/prctl.h>
@@ -100,7 +101,7 @@
*
* This is needed because all sockets created by the java.net APIs are IPv6 sockets, and on those
* sockets, IPv4 operations use IPv4-mapped addresses stored in a struct sockaddr_in6. But sockets
- * created using Posix.socket(AF_INET, ...) are IPv4 sockets and only support operations using IPv4
+ * created using Linux.socket(AF_INET, ...) are IPv4 sockets and only support operations using IPv4
* socket addresses structures.
*/
#define NET_IPV4_FALLBACK(jni_env, return_type, syscall_name, java_fd, java_addr, port, null_addr_ok, args...) ({ \
@@ -732,7 +733,155 @@
struct passwd* mResult;
};
-static jobject Posix_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
+static void AssertException(JNIEnv* env) {
+ if (env->ExceptionCheck() == JNI_FALSE) {
+ env->FatalError("Expected exception");
+ }
+}
+
+// Note for capabilities functions:
+// We assume the calls are rare enough that it does not make sense to cache class objects. The
+// advantage is lower maintenance burden.
+
+static bool ReadStructCapUserHeader(
+ JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
+ if (java_header == nullptr) {
+ jniThrowNullPointerException(env, "header is null");
+ return false;
+ }
+
+ ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+ if (header_class.get() == nullptr) {
+ return false;
+ }
+
+ {
+ static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
+ if (version_fid == nullptr) {
+ return false;
+ }
+ c_header->version = env->GetIntField(java_header, version_fid);
+ }
+
+ {
+ static jfieldID pid_fid = env->GetFieldID(header_class.get(), "pid", "I");
+ if (pid_fid == nullptr) {
+ return false;
+ }
+ c_header->pid = env->GetIntField(java_header, pid_fid);
+ }
+
+ return true;
+}
+
+static void SetStructCapUserHeaderVersion(
+ JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
+ ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+ if (header_class.get() == nullptr) {
+ env->ExceptionClear();
+ return;
+ }
+
+ static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
+ if (version_fid == nullptr) {
+ env->ExceptionClear();
+ return;
+ }
+ env->SetIntField(java_header, version_fid, c_header->version);
+}
+
+static jobject CreateStructCapUserData(
+ JNIEnv* env, jclass data_class, __user_cap_data_struct* c_data) {
+ if (c_data == nullptr) {
+ // Should not happen.
+ jniThrowNullPointerException(env, "data is null");
+ return nullptr;
+ }
+
+ static jmethodID data_cons = env->GetMethodID(data_class, "<init>", "(III)V");
+ if (data_cons == nullptr) {
+ return nullptr;
+ }
+
+ jint e = static_cast<jint>(c_data->effective);
+ jint p = static_cast<jint>(c_data->permitted);
+ jint i = static_cast<jint>(c_data->inheritable);
+ return env->NewObject(data_class, data_cons, e, p, i);
+}
+
+static bool ReadStructCapUserData(JNIEnv* env, jobject java_data, __user_cap_data_struct* c_data) {
+ if (java_data == nullptr) {
+ jniThrowNullPointerException(env, "data is null");
+ return false;
+ }
+
+ ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+ if (data_class.get() == nullptr) {
+ return false;
+ }
+
+ {
+ static jfieldID effective_fid = env->GetFieldID(data_class.get(), "effective", "I");
+ if (effective_fid == nullptr) {
+ return false;
+ }
+ c_data->effective = env->GetIntField(java_data, effective_fid);
+ }
+
+ {
+ static jfieldID permitted_fid = env->GetFieldID(data_class.get(), "permitted", "I");
+ if (permitted_fid == nullptr) {
+ return false;
+ }
+ c_data->permitted = env->GetIntField(java_data, permitted_fid);
+ }
+
+
+ {
+ static jfieldID inheritable_fid = env->GetFieldID(data_class.get(), "inheritable", "I");
+ if (inheritable_fid == nullptr) {
+ return false;
+ }
+ c_data->inheritable = env->GetIntField(java_data, inheritable_fid);
+ }
+
+ return true;
+}
+
+static constexpr size_t kMaxCapUserDataLength = 2U;
+#ifdef _LINUX_CAPABILITY_VERSION_1
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_1, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_2
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_2, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_3
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_3, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_4
+static_assert(false, "Unsupported capability version, please update.");
+#endif
+
+static size_t GetCapUserDataLength(uint32_t version) {
+#ifdef _LINUX_CAPABILITY_VERSION_1
+ if (version == _LINUX_CAPABILITY_VERSION_1) {
+ return _LINUX_CAPABILITY_U32S_1;
+ }
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_2
+ if (version == _LINUX_CAPABILITY_VERSION_2) {
+ return _LINUX_CAPABILITY_U32S_2;
+ }
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_3
+ if (version == _LINUX_CAPABILITY_VERSION_3) {
+ return _LINUX_CAPABILITY_U32S_3;
+ }
+#endif
+ return 0;
+}
+
+static jobject Linux_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
sockaddr_storage ss;
socklen_t sl = sizeof(ss);
memset(&ss, 0, sizeof(ss));
@@ -746,7 +895,7 @@
return (clientFd != -1) ? jniCreateFileDescriptor(env, clientFd) : NULL;
}
-static jboolean Posix_access(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static jboolean Linux_access(JNIEnv* env, jobject, jstring javaPath, jint mode) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return JNI_FALSE;
@@ -758,12 +907,12 @@
return (rc == 0);
}
-static void Posix_bind(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
+static void Linux_bind(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
// We don't need the return value because we'll already have thrown.
(void) NET_IPV4_FALLBACK(env, int, bind, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN);
}
-static void Posix_bindSocketAddress(
+static void Linux_bindSocketAddress(
JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
sockaddr_storage ss;
socklen_t sa_len;
@@ -776,7 +925,84 @@
(void) NET_FAILURE_RETRY(env, int, bind, javaFd, sa, sa_len);
}
-static void Posix_chmod(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static jobjectArray Linux_capget(JNIEnv* env, jobject, jobject header) {
+ // Convert Java header struct to kernel datastructure.
+ __user_cap_header_struct cap_header;
+ if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+ AssertException(env);
+ return nullptr;
+ }
+
+ // Call capget.
+ __user_cap_data_struct cap_data[kMaxCapUserDataLength];
+ if (capget(&cap_header, &cap_data[0]) == -1) {
+ // Check for EINVAL. In that case, mutate the header.
+ if (errno == EINVAL) {
+ int saved_errno = errno;
+ SetStructCapUserHeaderVersion(env, header, &cap_header);
+ errno = saved_errno;
+ }
+ throwErrnoException(env, "capget");
+ return nullptr;
+ }
+
+ // Create the result array.
+ ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+ if (data_class.get() == nullptr) {
+ return nullptr;
+ }
+ size_t result_size = GetCapUserDataLength(cap_header.version);
+ ScopedLocalRef<jobjectArray> result(
+ env, env->NewObjectArray(result_size, data_class.get(), nullptr));
+ if (result.get() == nullptr) {
+ return nullptr;
+ }
+ // Translate the values we got.
+ for (size_t i = 0; i < result_size; ++i) {
+ ScopedLocalRef<jobject> value(
+ env, CreateStructCapUserData(env, data_class.get(), &cap_data[i]));
+ if (value.get() == nullptr) {
+ AssertException(env);
+ return nullptr;
+ }
+ env->SetObjectArrayElement(result.get(), i, value.get());
+ }
+ return result.release();
+}
+
+static void Linux_capset(
+ JNIEnv* env, jobject, jobject header, jobjectArray data) {
+ // Convert Java header struct to kernel datastructure.
+ __user_cap_header_struct cap_header;
+ if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+ AssertException(env);
+ return;
+ }
+ size_t result_size = GetCapUserDataLength(cap_header.version);
+ // Ensure that the array has the expected length.
+ if (env->GetArrayLength(data) != static_cast<jint>(result_size)) {
+ jniThrowExceptionFmt(env,
+ "java/lang/IllegalArgumentException",
+ "Unsupported input length %d (expected %zu)",
+ env->GetArrayLength(data),
+ result_size);
+ return;
+ }
+
+ __user_cap_data_struct cap_data[kMaxCapUserDataLength];
+ // Translate the values we got.
+ for (size_t i = 0; i < result_size; ++i) {
+ ScopedLocalRef<jobject> value(env, env->GetObjectArrayElement(data, i));
+ if (!ReadStructCapUserData(env, value.get(), &cap_data[i])) {
+ AssertException(env);
+ return;
+ }
+ }
+
+ throwIfMinusOne(env, "capset", capset(&cap_header, &cap_data[0]));
+}
+
+static void Linux_chmod(JNIEnv* env, jobject, jstring javaPath, jint mode) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return;
@@ -784,7 +1010,7 @@
throwIfMinusOne(env, "chmod", TEMP_FAILURE_RETRY(chmod(path.c_str(), mode)));
}
-static void Posix_chown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
+static void Linux_chown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return;
@@ -792,7 +1018,7 @@
throwIfMinusOne(env, "chown", TEMP_FAILURE_RETRY(chown(path.c_str(), uid, gid)));
}
-static void Posix_close(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_close(JNIEnv* env, jobject, jobject javaFd) {
// Get the FileDescriptor's 'fd' field and clear it.
// We need to do this before we can throw an IOException (http://b/3222087).
int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -804,11 +1030,11 @@
throwIfMinusOne(env, "close", close(fd));
}
-static void Posix_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
+static void Linux_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
(void) NET_IPV4_FALLBACK(env, int, connect, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN);
}
-static void Posix_connectSocketAddress(
+static void Linux_connectSocketAddress(
JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
sockaddr_storage ss;
socklen_t sa_len;
@@ -821,24 +1047,24 @@
(void) NET_FAILURE_RETRY(env, int, connect, javaFd, sa, sa_len);
}
-static jobject Posix_dup(JNIEnv* env, jobject, jobject javaOldFd) {
+static jobject Linux_dup(JNIEnv* env, jobject, jobject javaOldFd) {
int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
int newFd = throwIfMinusOne(env, "dup", TEMP_FAILURE_RETRY(dup(oldFd)));
return (newFd != -1) ? jniCreateFileDescriptor(env, newFd) : NULL;
}
-static jobject Posix_dup2(JNIEnv* env, jobject, jobject javaOldFd, jint newFd) {
+static jobject Linux_dup2(JNIEnv* env, jobject, jobject javaOldFd, jint newFd) {
int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
int fd = throwIfMinusOne(env, "dup2", TEMP_FAILURE_RETRY(dup2(oldFd, newFd)));
return (fd != -1) ? jniCreateFileDescriptor(env, fd) : NULL;
}
-static jobjectArray Posix_environ(JNIEnv* env, jobject) {
+static jobjectArray Linux_environ(JNIEnv* env, jobject) {
extern char** environ; // Standard, but not in any header file.
return toStringArray(env, environ);
}
-static void Posix_execve(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv, jobjectArray javaEnvp) {
+static void Linux_execve(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv, jobjectArray javaEnvp) {
ScopedUtfChars path(env, javaFilename);
if (path.c_str() == NULL) {
return;
@@ -851,7 +1077,7 @@
throwErrnoException(env, "execve");
}
-static void Posix_execv(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv) {
+static void Linux_execv(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv) {
ScopedUtfChars path(env, javaFilename);
if (path.c_str() == NULL) {
return;
@@ -863,17 +1089,17 @@
throwErrnoException(env, "execv");
}
-static void Posix_fchmod(JNIEnv* env, jobject, jobject javaFd, jint mode) {
+static void Linux_fchmod(JNIEnv* env, jobject, jobject javaFd, jint mode) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "fchmod", TEMP_FAILURE_RETRY(fchmod(fd, mode)));
}
-static void Posix_fchown(JNIEnv* env, jobject, jobject javaFd, jint uid, jint gid) {
+static void Linux_fchown(JNIEnv* env, jobject, jobject javaFd, jint uid, jint gid) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "fchown", TEMP_FAILURE_RETRY(fchown(fd, uid, gid)));
}
-static jint Posix_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaFlock) {
+static jint Linux_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaFlock) {
static jfieldID typeFid = env->GetFieldID(JniConstants::structFlockClass, "l_type", "S");
static jfieldID whenceFid = env->GetFieldID(JniConstants::structFlockClass, "l_whence", "S");
static jfieldID startFid = env->GetFieldID(JniConstants::structFlockClass, "l_start", "J");
@@ -899,22 +1125,22 @@
return rc;
}
-static jint Posix_fcntlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jint arg) {
+static jint Linux_fcntlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jint arg) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd, arg)));
}
-static jint Posix_fcntlVoid(JNIEnv* env, jobject, jobject javaFd, jint cmd) {
+static jint Linux_fcntlVoid(JNIEnv* env, jobject, jobject javaFd, jint cmd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd)));
}
-static void Posix_fdatasync(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_fdatasync(JNIEnv* env, jobject, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "fdatasync", TEMP_FAILURE_RETRY(fdatasync(fd)));
}
-static jobject Posix_fstat(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_fstat(JNIEnv* env, jobject, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
struct stat64 sb;
int rc = TEMP_FAILURE_RETRY(fstat64(fd, &sb));
@@ -925,7 +1151,7 @@
return makeStructStat(env, sb);
}
-static jobject Posix_fstatvfs(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_fstatvfs(JNIEnv* env, jobject, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
struct statvfs sb;
int rc = TEMP_FAILURE_RETRY(fstatvfs(fd, &sb));
@@ -936,21 +1162,21 @@
return makeStructStatVfs(env, sb);
}
-static void Posix_fsync(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_fsync(JNIEnv* env, jobject, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "fsync", TEMP_FAILURE_RETRY(fsync(fd)));
}
-static void Posix_ftruncate(JNIEnv* env, jobject, jobject javaFd, jlong length) {
+static void Linux_ftruncate(JNIEnv* env, jobject, jobject javaFd, jlong length) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "ftruncate", TEMP_FAILURE_RETRY(ftruncate64(fd, length)));
}
-static jstring Posix_gai_strerror(JNIEnv* env, jobject, jint error) {
+static jstring Linux_gai_strerror(JNIEnv* env, jobject, jint error) {
return env->NewStringUTF(gai_strerror(error));
}
-static jobjectArray Posix_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,
+static jobjectArray Linux_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,
jobject javaHints, jint netId) {
ScopedUtfChars node(env, javaNode);
if (node.c_str() == NULL) {
@@ -1018,19 +1244,19 @@
return result;
}
-static jint Posix_getegid(JNIEnv*, jobject) {
+static jint Linux_getegid(JNIEnv*, jobject) {
return getegid();
}
-static jint Posix_geteuid(JNIEnv*, jobject) {
+static jint Linux_geteuid(JNIEnv*, jobject) {
return geteuid();
}
-static jint Posix_getgid(JNIEnv*, jobject) {
+static jint Linux_getgid(JNIEnv*, jobject) {
return getgid();
}
-static jstring Posix_getenv(JNIEnv* env, jobject, jstring javaName) {
+static jstring Linux_getenv(JNIEnv* env, jobject, jstring javaName) {
ScopedUtfChars name(env, javaName);
if (name.c_str() == NULL) {
return NULL;
@@ -1038,7 +1264,7 @@
return env->NewStringUTF(getenv(name.c_str()));
}
-static jstring Posix_getnameinfo(JNIEnv* env, jobject, jobject javaAddress, jint flags) {
+static jstring Linux_getnameinfo(JNIEnv* env, jobject, jobject javaAddress, jint flags) {
sockaddr_storage ss;
socklen_t sa_len;
if (!inetAddressToSockaddrVerbatim(env, javaAddress, 0, ss, sa_len)) {
@@ -1054,23 +1280,23 @@
return env->NewStringUTF(buf);
}
-static jobject Posix_getpeername(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_getpeername(JNIEnv* env, jobject, jobject javaFd) {
return doGetSockName(env, javaFd, false);
}
-static jint Posix_getpgid(JNIEnv* env, jobject, jint pid) {
+static jint Linux_getpgid(JNIEnv* env, jobject, jint pid) {
return throwIfMinusOne(env, "getpgid", TEMP_FAILURE_RETRY(getpgid(pid)));
}
-static jint Posix_getpid(JNIEnv*, jobject) {
+static jint Linux_getpid(JNIEnv*, jobject) {
return TEMP_FAILURE_RETRY(getpid());
}
-static jint Posix_getppid(JNIEnv*, jobject) {
+static jint Linux_getppid(JNIEnv*, jobject) {
return TEMP_FAILURE_RETRY(getppid());
}
-static jobject Posix_getpwnam(JNIEnv* env, jobject, jstring javaName) {
+static jobject Linux_getpwnam(JNIEnv* env, jobject, jstring javaName) {
ScopedUtfChars name(env, javaName);
if (name.c_str() == NULL) {
return NULL;
@@ -1078,15 +1304,15 @@
return Passwd(env).getpwnam(name.c_str());
}
-static jobject Posix_getpwuid(JNIEnv* env, jobject, jint uid) {
+static jobject Linux_getpwuid(JNIEnv* env, jobject, jint uid) {
return Passwd(env).getpwuid(uid);
}
-static jobject Posix_getsockname(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_getsockname(JNIEnv* env, jobject, jobject javaFd) {
return doGetSockName(env, javaFd, true);
}
-static jint Posix_getsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jint Linux_getsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
u_char result = 0;
socklen_t size = sizeof(result);
@@ -1094,7 +1320,7 @@
return result;
}
-static jobject Posix_getsockoptInAddr(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptInAddr(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
sockaddr_storage ss;
memset(&ss, 0, sizeof(ss));
@@ -1109,7 +1335,7 @@
return sockaddrToInetAddress(env, ss, NULL);
}
-static jint Posix_getsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jint Linux_getsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
jint result = 0;
socklen_t size = sizeof(result);
@@ -1117,7 +1343,7 @@
return result;
}
-static jobject Posix_getsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
struct linger l;
socklen_t size = sizeof(l);
@@ -1130,7 +1356,7 @@
return makeStructLinger(env, l);
}
-static jobject Posix_getsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
struct timeval tv;
socklen_t size = sizeof(tv);
@@ -1143,7 +1369,7 @@
return makeStructTimeval(env, tv);
}
-static jobject Posix_getsockoptUcred(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptUcred(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
struct ucred u;
socklen_t size = sizeof(u);
@@ -1156,7 +1382,7 @@
return makeStructUcred(env, u);
}
-static jint Posix_gettid(JNIEnv* env __unused, jobject) {
+static jint Linux_gettid(JNIEnv* env __unused, jobject) {
#if defined(__BIONIC__)
return TEMP_FAILURE_RETRY(gettid());
#else
@@ -1164,11 +1390,11 @@
#endif
}
-static jint Posix_getuid(JNIEnv*, jobject) {
+static jint Linux_getuid(JNIEnv*, jobject) {
return getuid();
}
-static jbyteArray Posix_getxattr(JNIEnv* env, jobject, jstring javaPath,
+static jbyteArray Linux_getxattr(JNIEnv* env, jobject, jstring javaPath,
jstring javaName) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
@@ -1207,7 +1433,7 @@
}
}
-static jobjectArray Posix_getifaddrs(JNIEnv* env, jobject) {
+static jobjectArray Linux_getifaddrs(JNIEnv* env, jobject) {
static jmethodID ctor = env->GetMethodID(JniConstants::structIfaddrs, "<init>",
"(Ljava/lang/String;ILjava/net/InetAddress;Ljava/net/InetAddress;Ljava/net/InetAddress;[B)V");
@@ -1302,7 +1528,7 @@
return result;
}
-static jstring Posix_if_indextoname(JNIEnv* env, jobject, jint index) {
+static jstring Linux_if_indextoname(JNIEnv* env, jobject, jint index) {
char buf[IF_NAMESIZE];
char* name = if_indextoname(index, buf);
// if_indextoname(3) returns NULL on failure, which will come out of NewStringUTF unscathed.
@@ -1310,7 +1536,7 @@
return env->NewStringUTF(name);
}
-static jint Posix_if_nametoindex(JNIEnv* env, jobject, jstring name) {
+static jint Linux_if_nametoindex(JNIEnv* env, jobject, jstring name) {
ScopedUtfChars cname(env, name);
if (cname.c_str() == NULL) {
return 0;
@@ -1320,7 +1546,7 @@
return if_nametoindex(cname.c_str());
}
-static jobject Posix_inet_pton(JNIEnv* env, jobject, jint family, jstring javaName) {
+static jobject Linux_inet_pton(JNIEnv* env, jobject, jint family, jstring javaName) {
ScopedUtfChars name(env, javaName);
if (name.c_str() == NULL) {
return NULL;
@@ -1336,7 +1562,7 @@
return sockaddrToInetAddress(env, ss, NULL);
}
-static jint Posix_ioctlFlags(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
+static jint Linux_ioctlFlags(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
struct ifreq req;
if (!fillIfreq(env, javaInterfaceName, req)) {
return 0;
@@ -1346,7 +1572,7 @@
return req.ifr_flags;
}
-static jobject Posix_ioctlInetAddress(JNIEnv* env, jobject, jobject javaFd, jint cmd, jstring javaInterfaceName) {
+static jobject Linux_ioctlInetAddress(JNIEnv* env, jobject, jobject javaFd, jint cmd, jstring javaInterfaceName) {
struct ifreq req;
if (!fillIfreq(env, javaInterfaceName, req)) {
return NULL;
@@ -1359,7 +1585,7 @@
return sockaddrToInetAddress(env, reinterpret_cast<sockaddr_storage&>(req.ifr_addr), NULL);
}
-static jint Posix_ioctlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaArg) {
+static jint Linux_ioctlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaArg) {
// This is complicated because ioctls may return their result by updating their argument
// or via their return value, so we need to support both.
int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -1372,7 +1598,7 @@
return rc;
}
-static jint Posix_ioctlMTU(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
+static jint Linux_ioctlMTU(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
struct ifreq req;
if (!fillIfreq(env, javaInterfaceName, req)) {
return 0;
@@ -1382,16 +1608,16 @@
return req.ifr_mtu;
}
-static jboolean Posix_isatty(JNIEnv* env, jobject, jobject javaFd) {
+static jboolean Linux_isatty(JNIEnv* env, jobject, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
return TEMP_FAILURE_RETRY(isatty(fd)) == 1;
}
-static void Posix_kill(JNIEnv* env, jobject, jint pid, jint sig) {
+static void Linux_kill(JNIEnv* env, jobject, jint pid, jint sig) {
throwIfMinusOne(env, "kill", TEMP_FAILURE_RETRY(kill(pid, sig)));
}
-static void Posix_lchown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
+static void Linux_lchown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return;
@@ -1399,7 +1625,7 @@
throwIfMinusOne(env, "lchown", TEMP_FAILURE_RETRY(lchown(path.c_str(), uid, gid)));
}
-static void Posix_link(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
+static void Linux_link(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
ScopedUtfChars oldPath(env, javaOldPath);
if (oldPath.c_str() == NULL) {
return;
@@ -1411,12 +1637,12 @@
throwIfMinusOne(env, "link", TEMP_FAILURE_RETRY(link(oldPath.c_str(), newPath.c_str())));
}
-static void Posix_listen(JNIEnv* env, jobject, jobject javaFd, jint backlog) {
+static void Linux_listen(JNIEnv* env, jobject, jobject javaFd, jint backlog) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "listen", TEMP_FAILURE_RETRY(listen(fd, backlog)));
}
-static jobjectArray Posix_listxattr(JNIEnv* env, jobject, jstring javaPath) {
+static jobjectArray Linux_listxattr(JNIEnv* env, jobject, jstring javaPath) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return NULL;
@@ -1451,16 +1677,16 @@
}
}
-static jlong Posix_lseek(JNIEnv* env, jobject, jobject javaFd, jlong offset, jint whence) {
+static jlong Linux_lseek(JNIEnv* env, jobject, jobject javaFd, jlong offset, jint whence) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
return throwIfMinusOne(env, "lseek", TEMP_FAILURE_RETRY(lseek64(fd, offset, whence)));
}
-static jobject Posix_lstat(JNIEnv* env, jobject, jstring javaPath) {
+static jobject Linux_lstat(JNIEnv* env, jobject, jstring javaPath) {
return doStat(env, javaPath, true);
}
-static void Posix_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) {
+static void Linux_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) {
ScopedByteArrayRW vector(env, javaVector);
if (vector.get() == NULL) {
return;
@@ -1470,7 +1696,7 @@
throwIfMinusOne(env, "mincore", TEMP_FAILURE_RETRY(mincore(ptr, byteCount, vec)));
}
-static void Posix_mkdir(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static void Linux_mkdir(JNIEnv* env, jobject, jstring javaPath, jint mode) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return;
@@ -1478,7 +1704,7 @@
throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), mode)));
}
-static void Posix_mkfifo(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static void Linux_mkfifo(JNIEnv* env, jobject, jstring javaPath, jint mode) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return;
@@ -1486,12 +1712,12 @@
throwIfMinusOne(env, "mkfifo", TEMP_FAILURE_RETRY(mkfifo(path.c_str(), mode)));
}
-static void Posix_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
+static void Linux_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
throwIfMinusOne(env, "mlock", TEMP_FAILURE_RETRY(mlock(ptr, byteCount)));
}
-static jlong Posix_mmap(JNIEnv* env, jobject, jlong address, jlong byteCount, jint prot, jint flags, jobject javaFd, jlong offset) {
+static jlong Linux_mmap(JNIEnv* env, jobject, jlong address, jlong byteCount, jint prot, jint flags, jobject javaFd, jlong offset) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
void* suggestedPtr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
void* ptr = mmap64(suggestedPtr, byteCount, prot, flags, fd, offset);
@@ -1501,22 +1727,22 @@
return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
}
-static void Posix_msync(JNIEnv* env, jobject, jlong address, jlong byteCount, jint flags) {
+static void Linux_msync(JNIEnv* env, jobject, jlong address, jlong byteCount, jint flags) {
void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
throwIfMinusOne(env, "msync", TEMP_FAILURE_RETRY(msync(ptr, byteCount, flags)));
}
-static void Posix_munlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
+static void Linux_munlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
throwIfMinusOne(env, "munlock", TEMP_FAILURE_RETRY(munlock(ptr, byteCount)));
}
-static void Posix_munmap(JNIEnv* env, jobject, jlong address, jlong byteCount) {
+static void Linux_munmap(JNIEnv* env, jobject, jlong address, jlong byteCount) {
void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
throwIfMinusOne(env, "munmap", TEMP_FAILURE_RETRY(munmap(ptr, byteCount)));
}
-static jobject Posix_open(JNIEnv* env, jobject, jstring javaPath, jint flags, jint mode) {
+static jobject Linux_open(JNIEnv* env, jobject, jstring javaPath, jint flags, jint mode) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return NULL;
@@ -1525,7 +1751,7 @@
return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
}
-static jobjectArray Posix_pipe2(JNIEnv* env, jobject, jint flags __unused) {
+static jobjectArray Linux_pipe2(JNIEnv* env, jobject, jint flags __unused) {
int fds[2];
throwIfMinusOne(env, "pipe2", TEMP_FAILURE_RETRY(pipe2(&fds[0], flags)));
jobjectArray result = env->NewObjectArray(2, JniConstants::fileDescriptorClass, NULL);
@@ -1545,7 +1771,7 @@
return result;
}
-static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) {
+static jint Linux_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) {
static jfieldID fdFid = env->GetFieldID(JniConstants::structPollfdClass, "fd", "Ljava/io/FileDescriptor;");
static jfieldID eventsFid = env->GetFieldID(JniConstants::structPollfdClass, "events", "S");
static jfieldID reventsFid = env->GetFieldID(JniConstants::structPollfdClass, "revents", "S");
@@ -1626,7 +1852,7 @@
return rc;
}
-static void Posix_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
+static void Linux_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
jlong offset __unused, jlong length __unused) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
while ((errno = posix_fallocate64(fd, offset, length)) == EINTR) {
@@ -1636,7 +1862,7 @@
}
}
-static jint Posix_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
+static jint Linux_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
jlong arg3 __unused, jlong arg4 __unused, jlong arg5 __unused) {
int result = TEMP_FAILURE_RETRY(prctl(static_cast<int>(option),
static_cast<unsigned long>(arg2),
@@ -1646,7 +1872,7 @@
return throwIfMinusOne(env, "prctl", result);
}
-static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
+static jint Linux_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
ScopedBytesRW bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
@@ -1654,7 +1880,7 @@
return IO_FAILURE_RETRY(env, ssize_t, pread64, javaFd, bytes.get() + byteOffset, byteCount, offset);
}
-static jint Posix_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) {
+static jint Linux_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) {
ScopedBytesRO bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
@@ -1662,7 +1888,7 @@
return IO_FAILURE_RETRY(env, ssize_t, pwrite64, javaFd, bytes.get() + byteOffset, byteCount, offset);
}
-static jint Posix_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
+static jint Linux_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
ScopedBytesRW bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
@@ -1670,7 +1896,7 @@
return IO_FAILURE_RETRY(env, ssize_t, read, javaFd, bytes.get() + byteOffset, byteCount);
}
-static jstring Posix_readlink(JNIEnv* env, jobject, jstring javaPath) {
+static jstring Linux_readlink(JNIEnv* env, jobject, jstring javaPath) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return NULL;
@@ -1684,7 +1910,7 @@
return env->NewStringUTF(result.c_str());
}
-static jstring Posix_realpath(JNIEnv* env, jobject, jstring javaPath) {
+static jstring Linux_realpath(JNIEnv* env, jobject, jstring javaPath) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return NULL;
@@ -1699,7 +1925,7 @@
return env->NewStringUTF(real_path.get());
}
-static jint Posix_readv(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
+static jint Linux_readv(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
IoVec<ScopedBytesRW> ioVec(env, env->GetArrayLength(buffers));
if (!ioVec.init(buffers, offsets, byteCounts)) {
return -1;
@@ -1707,7 +1933,7 @@
return IO_FAILURE_RETRY(env, ssize_t, readv, javaFd, ioVec.get(), ioVec.size());
}
-static jint Posix_recvfromBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetSocketAddress) {
+static jint Linux_recvfromBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetSocketAddress) {
ScopedBytesRW bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
@@ -1729,7 +1955,7 @@
return recvCount;
}
-static void Posix_remove(JNIEnv* env, jobject, jstring javaPath) {
+static void Linux_remove(JNIEnv* env, jobject, jstring javaPath) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return;
@@ -1737,7 +1963,7 @@
throwIfMinusOne(env, "remove", TEMP_FAILURE_RETRY(remove(path.c_str())));
}
-static void Posix_removexattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName) {
+static void Linux_removexattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return;
@@ -1753,7 +1979,7 @@
}
}
-static void Posix_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
+static void Linux_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
ScopedUtfChars oldPath(env, javaOldPath);
if (oldPath.c_str() == NULL) {
return;
@@ -1765,7 +1991,7 @@
throwIfMinusOne(env, "rename", TEMP_FAILURE_RETRY(rename(oldPath.c_str(), newPath.c_str())));
}
-static jlong Posix_sendfile(JNIEnv* env, jobject, jobject javaOutFd, jobject javaInFd, jobject javaOffset, jlong byteCount) {
+static jlong Linux_sendfile(JNIEnv* env, jobject, jobject javaOutFd, jobject javaInFd, jobject javaOffset, jlong byteCount) {
int outFd = jniGetFDFromFileDescriptor(env, javaOutFd);
int inFd = jniGetFDFromFileDescriptor(env, javaInFd);
static jfieldID valueFid = env->GetFieldID(JniConstants::mutableLongClass, "value", "J");
@@ -1783,7 +2009,7 @@
return result;
}
-static jint Posix_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) {
+static jint Linux_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) {
ScopedBytesRO bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
@@ -1793,13 +2019,13 @@
NULL_ADDR_OK, bytes.get() + byteOffset, byteCount, flags);
}
-static jint Posix_sendtoBytesSocketAddress(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaSocketAddress) {
+static jint Linux_sendtoBytesSocketAddress(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaSocketAddress) {
if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
// Use the InetAddress version so we get the benefit of NET_IPV4_FALLBACK.
jobject javaInetAddress;
jint port;
javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port);
- return Posix_sendtoBytes(env, NULL, javaFd, javaBytes, byteOffset, byteCount, flags,
+ return Linux_sendtoBytes(env, NULL, javaFd, javaBytes, byteOffset, byteCount, flags,
javaInetAddress, port);
}
@@ -1819,11 +2045,11 @@
return NET_FAILURE_RETRY(env, ssize_t, sendto, javaFd, bytes.get() + byteOffset, byteCount, flags, sa, sa_len);
}
-static void Posix_setegid(JNIEnv* env, jobject, jint egid) {
+static void Linux_setegid(JNIEnv* env, jobject, jint egid) {
throwIfMinusOne(env, "setegid", TEMP_FAILURE_RETRY(setegid(egid)));
}
-static void Posix_setenv(JNIEnv* env, jobject, jstring javaName, jstring javaValue, jboolean overwrite) {
+static void Linux_setenv(JNIEnv* env, jobject, jstring javaName, jstring javaValue, jboolean overwrite) {
ScopedUtfChars name(env, javaName);
if (name.c_str() == NULL) {
return;
@@ -1835,37 +2061,37 @@
throwIfMinusOne(env, "setenv", setenv(name.c_str(), value.c_str(), overwrite));
}
-static void Posix_seteuid(JNIEnv* env, jobject, jint euid) {
+static void Linux_seteuid(JNIEnv* env, jobject, jint euid) {
throwIfMinusOne(env, "seteuid", TEMP_FAILURE_RETRY(seteuid(euid)));
}
-static void Posix_setgid(JNIEnv* env, jobject, jint gid) {
+static void Linux_setgid(JNIEnv* env, jobject, jint gid) {
throwIfMinusOne(env, "setgid", TEMP_FAILURE_RETRY(setgid(gid)));
}
-static void Posix_setpgid(JNIEnv* env, jobject, jint pid, int pgid) {
+static void Linux_setpgid(JNIEnv* env, jobject, jint pid, int pgid) {
throwIfMinusOne(env, "setpgid", TEMP_FAILURE_RETRY(setpgid(pid, pgid)));
}
-static void Posix_setregid(JNIEnv* env, jobject, jint rgid, int egid) {
+static void Linux_setregid(JNIEnv* env, jobject, jint rgid, int egid) {
throwIfMinusOne(env, "setregid", TEMP_FAILURE_RETRY(setregid(rgid, egid)));
}
-static void Posix_setreuid(JNIEnv* env, jobject, jint ruid, int euid) {
+static void Linux_setreuid(JNIEnv* env, jobject, jint ruid, int euid) {
throwIfMinusOne(env, "setreuid", TEMP_FAILURE_RETRY(setreuid(ruid, euid)));
}
-static jint Posix_setsid(JNIEnv* env, jobject) {
+static jint Linux_setsid(JNIEnv* env, jobject) {
return throwIfMinusOne(env, "setsid", TEMP_FAILURE_RETRY(setsid()));
}
-static void Posix_setsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
+static void Linux_setsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
u_char byte = value;
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &byte, sizeof(byte))));
}
-static void Posix_setsockoptIfreq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jstring javaInterfaceName) {
+static void Linux_setsockoptIfreq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jstring javaInterfaceName) {
struct ifreq req;
if (!fillIfreq(env, javaInterfaceName, req)) {
return;
@@ -1874,12 +2100,12 @@
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
}
-static void Posix_setsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
+static void Linux_setsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
}
-static void Posix_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
+static void Linux_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
ip_mreqn req;
memset(&req, 0, sizeof(req));
req.imr_ifindex = value;
@@ -1887,7 +2113,7 @@
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
}
-static void Posix_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupReq) {
+static void Linux_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupReq) {
struct group_req req;
memset(&req, 0, sizeof(req));
@@ -1920,7 +2146,7 @@
throwIfMinusOne(env, "setsockopt", rc);
}
-static void Posix_setsockoptGroupSourceReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupSourceReq) {
+static void Linux_setsockoptGroupSourceReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupSourceReq) {
socklen_t sa_len;
struct group_source_req req;
memset(&req, 0, sizeof(req));
@@ -1962,7 +2188,7 @@
throwIfMinusOne(env, "setsockopt", rc);
}
-static void Posix_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
+static void Linux_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
static jfieldID lOnoffFid = env->GetFieldID(JniConstants::structLingerClass, "l_onoff", "I");
static jfieldID lLingerFid = env->GetFieldID(JniConstants::structLingerClass, "l_linger", "I");
int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -1972,7 +2198,7 @@
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
}
-static void Posix_setsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaTimeval) {
+static void Linux_setsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaTimeval) {
static jfieldID tvSecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_sec", "J");
static jfieldID tvUsecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_usec", "J");
int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -1982,11 +2208,11 @@
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
}
-static void Posix_setuid(JNIEnv* env, jobject, jint uid) {
+static void Linux_setuid(JNIEnv* env, jobject, jint uid) {
throwIfMinusOne(env, "setuid", TEMP_FAILURE_RETRY(setuid(uid)));
}
-static void Posix_setxattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName,
+static void Linux_setxattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName,
jbyteArray javaValue, jint flags) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
@@ -2007,12 +2233,12 @@
}
}
-static void Posix_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) {
+static void Linux_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "shutdown", TEMP_FAILURE_RETRY(shutdown(fd, how)));
}
-static jobject Posix_socket(JNIEnv* env, jobject, jint domain, jint type, jint protocol) {
+static jobject Linux_socket(JNIEnv* env, jobject, jint domain, jint type, jint protocol) {
if (domain == AF_PACKET) {
protocol = htons(protocol); // Packet sockets specify the protocol in host byte order.
}
@@ -2020,7 +2246,7 @@
return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
}
-static void Posix_socketpair(JNIEnv* env, jobject, jint domain, jint type, jint protocol, jobject javaFd1, jobject javaFd2) {
+static void Linux_socketpair(JNIEnv* env, jobject, jint domain, jint type, jint protocol, jobject javaFd1, jobject javaFd2) {
int fds[2];
int rc = throwIfMinusOne(env, "socketpair", TEMP_FAILURE_RETRY(socketpair(domain, type, protocol, fds)));
if (rc != -1) {
@@ -2029,11 +2255,11 @@
}
}
-static jobject Posix_stat(JNIEnv* env, jobject, jstring javaPath) {
+static jobject Linux_stat(JNIEnv* env, jobject, jstring javaPath) {
return doStat(env, javaPath, false);
}
-static jobject Posix_statvfs(JNIEnv* env, jobject, jstring javaPath) {
+static jobject Linux_statvfs(JNIEnv* env, jobject, jstring javaPath) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
return NULL;
@@ -2047,17 +2273,17 @@
return makeStructStatVfs(env, sb);
}
-static jstring Posix_strerror(JNIEnv* env, jobject, jint errnum) {
+static jstring Linux_strerror(JNIEnv* env, jobject, jint errnum) {
char buffer[BUFSIZ];
const char* message = jniStrError(errnum, buffer, sizeof(buffer));
return env->NewStringUTF(message);
}
-static jstring Posix_strsignal(JNIEnv* env, jobject, jint signal) {
+static jstring Linux_strsignal(JNIEnv* env, jobject, jint signal) {
return env->NewStringUTF(strsignal(signal));
}
-static void Posix_symlink(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
+static void Linux_symlink(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
ScopedUtfChars oldPath(env, javaOldPath);
if (oldPath.c_str() == NULL) {
return;
@@ -2069,7 +2295,7 @@
throwIfMinusOne(env, "symlink", TEMP_FAILURE_RETRY(symlink(oldPath.c_str(), newPath.c_str())));
}
-static jlong Posix_sysconf(JNIEnv* env, jobject, jint name) {
+static jlong Linux_sysconf(JNIEnv* env, jobject, jint name) {
// Since -1 is a valid result from sysconf(3), detecting failure is a little more awkward.
errno = 0;
long result = sysconf(name);
@@ -2079,21 +2305,21 @@
return result;
}
-static void Posix_tcdrain(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_tcdrain(JNIEnv* env, jobject, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "tcdrain", TEMP_FAILURE_RETRY(tcdrain(fd)));
}
-static void Posix_tcsendbreak(JNIEnv* env, jobject, jobject javaFd, jint duration) {
+static void Linux_tcsendbreak(JNIEnv* env, jobject, jobject javaFd, jint duration) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "tcsendbreak", TEMP_FAILURE_RETRY(tcsendbreak(fd, duration)));
}
-static jint Posix_umaskImpl(JNIEnv*, jobject, jint mask) {
+static jint Linux_umaskImpl(JNIEnv*, jobject, jint mask) {
return umask(mask);
}
-static jobject Posix_uname(JNIEnv* env, jobject) {
+static jobject Linux_uname(JNIEnv* env, jobject) {
struct utsname buf;
if (TEMP_FAILURE_RETRY(uname(&buf)) == -1) {
return NULL; // Can't happen.
@@ -2101,7 +2327,7 @@
return makeStructUtsname(env, buf);
}
-static void Posix_unlink(JNIEnv* env, jobject, jstring javaPathname) {
+static void Linux_unlink(JNIEnv* env, jobject, jstring javaPathname) {
ScopedUtfChars pathname(env, javaPathname);
if (pathname.c_str() == NULL) {
return;
@@ -2109,7 +2335,7 @@
throwIfMinusOne(env, "unlink", unlink(pathname.c_str()));
}
-static void Posix_unsetenv(JNIEnv* env, jobject, jstring javaName) {
+static void Linux_unsetenv(JNIEnv* env, jobject, jstring javaName) {
ScopedUtfChars name(env, javaName);
if (name.c_str() == NULL) {
return;
@@ -2117,7 +2343,7 @@
throwIfMinusOne(env, "unsetenv", unsetenv(name.c_str()));
}
-static jint Posix_waitpid(JNIEnv* env, jobject, jint pid, jobject javaStatus, jint options) {
+static jint Linux_waitpid(JNIEnv* env, jobject, jint pid, jobject javaStatus, jint options) {
int status;
int rc = throwIfMinusOne(env, "waitpid", TEMP_FAILURE_RETRY(waitpid(pid, &status, options)));
if (rc != -1) {
@@ -2127,7 +2353,7 @@
return rc;
}
-static jint Posix_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) {
+static jint Linux_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) {
ScopedBytesRO bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
@@ -2135,7 +2361,7 @@
return IO_FAILURE_RETRY(env, ssize_t, write, javaFd, bytes.get() + byteOffset, byteCount);
}
-static jint Posix_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
+static jint Linux_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
IoVec<ScopedBytesRO> ioVec(env, env->GetArrayLength(buffers));
if (!ioVec.init(buffers, offsets, byteCounts)) {
return -1;
@@ -2147,132 +2373,136 @@
{ #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName ## variant) }
static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)Ljava/io/FileDescriptor;"),
- NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"),
- NATIVE_METHOD(Posix, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
- NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
- NATIVE_METHOD_OVERLOAD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
- NATIVE_METHOD(Posix, chmod, "(Ljava/lang/String;I)V"),
- NATIVE_METHOD(Posix, chown, "(Ljava/lang/String;II)V"),
- NATIVE_METHOD(Posix, close, "(Ljava/io/FileDescriptor;)V"),
- NATIVE_METHOD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
- NATIVE_METHOD_OVERLOAD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
- NATIVE_METHOD(Posix, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"),
- NATIVE_METHOD(Posix, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"),
- NATIVE_METHOD(Posix, environ, "()[Ljava/lang/String;"),
- NATIVE_METHOD(Posix, execv, "(Ljava/lang/String;[Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, execve, "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, fchmod, "(Ljava/io/FileDescriptor;I)V"),
- NATIVE_METHOD(Posix, fchown, "(Ljava/io/FileDescriptor;II)V"),
- NATIVE_METHOD(Posix, fcntlFlock, "(Ljava/io/FileDescriptor;ILandroid/system/StructFlock;)I"),
- NATIVE_METHOD(Posix, fcntlInt, "(Ljava/io/FileDescriptor;II)I"),
- NATIVE_METHOD(Posix, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"),
- NATIVE_METHOD(Posix, fdatasync, "(Ljava/io/FileDescriptor;)V"),
- NATIVE_METHOD(Posix, fstat, "(Ljava/io/FileDescriptor;)Landroid/system/StructStat;"),
- NATIVE_METHOD(Posix, fstatvfs, "(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;"),
- NATIVE_METHOD(Posix, fsync, "(Ljava/io/FileDescriptor;)V"),
- NATIVE_METHOD(Posix, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
- NATIVE_METHOD(Posix, gai_strerror, "(I)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, getegid, "()I"),
- NATIVE_METHOD(Posix, geteuid, "()I"),
- NATIVE_METHOD(Posix, getgid, "()I"),
- NATIVE_METHOD(Posix, getenv, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, getnameinfo, "(Ljava/net/InetAddress;I)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, getpeername, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
- NATIVE_METHOD(Posix, getpgid, "(I)I"),
- NATIVE_METHOD(Posix, getpid, "()I"),
- NATIVE_METHOD(Posix, getppid, "()I"),
- NATIVE_METHOD(Posix, getpwnam, "(Ljava/lang/String;)Landroid/system/StructPasswd;"),
- NATIVE_METHOD(Posix, getpwuid, "(I)Landroid/system/StructPasswd;"),
- NATIVE_METHOD(Posix, getsockname, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
- NATIVE_METHOD(Posix, getsockoptByte, "(Ljava/io/FileDescriptor;II)I"),
- NATIVE_METHOD(Posix, getsockoptInAddr, "(Ljava/io/FileDescriptor;II)Ljava/net/InetAddress;"),
- NATIVE_METHOD(Posix, getsockoptInt, "(Ljava/io/FileDescriptor;II)I"),
- NATIVE_METHOD(Posix, getsockoptLinger, "(Ljava/io/FileDescriptor;II)Landroid/system/StructLinger;"),
- NATIVE_METHOD(Posix, getsockoptTimeval, "(Ljava/io/FileDescriptor;II)Landroid/system/StructTimeval;"),
- NATIVE_METHOD(Posix, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"),
- NATIVE_METHOD(Posix, gettid, "()I"),
- NATIVE_METHOD(Posix, getuid, "()I"),
- NATIVE_METHOD(Posix, getxattr, "(Ljava/lang/String;Ljava/lang/String;)[B"),
- NATIVE_METHOD(Posix, getifaddrs, "()[Landroid/system/StructIfaddrs;"),
- NATIVE_METHOD(Posix, if_indextoname, "(I)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, if_nametoindex, "(Ljava/lang/String;)I"),
- NATIVE_METHOD(Posix, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
- NATIVE_METHOD(Posix, ioctlFlags, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
- NATIVE_METHOD(Posix, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
- NATIVE_METHOD(Posix, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/util/MutableInt;)I"),
- NATIVE_METHOD(Posix, ioctlMTU, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
- NATIVE_METHOD(Posix, isatty, "(Ljava/io/FileDescriptor;)Z"),
- NATIVE_METHOD(Posix, kill, "(II)V"),
- NATIVE_METHOD(Posix, lchown, "(Ljava/lang/String;II)V"),
- NATIVE_METHOD(Posix, link, "(Ljava/lang/String;Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, listen, "(Ljava/io/FileDescriptor;I)V"),
- NATIVE_METHOD(Posix, listxattr, "(Ljava/lang/String;)[Ljava/lang/String;"),
- NATIVE_METHOD(Posix, lseek, "(Ljava/io/FileDescriptor;JI)J"),
- NATIVE_METHOD(Posix, lstat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
- NATIVE_METHOD(Posix, mincore, "(JJ[B)V"),
- NATIVE_METHOD(Posix, mkdir, "(Ljava/lang/String;I)V"),
- NATIVE_METHOD(Posix, mkfifo, "(Ljava/lang/String;I)V"),
- NATIVE_METHOD(Posix, mlock, "(JJ)V"),
- NATIVE_METHOD(Posix, mmap, "(JJIILjava/io/FileDescriptor;J)J"),
- NATIVE_METHOD(Posix, msync, "(JJI)V"),
- NATIVE_METHOD(Posix, munlock, "(JJ)V"),
- NATIVE_METHOD(Posix, munmap, "(JJ)V"),
- NATIVE_METHOD(Posix, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"),
- NATIVE_METHOD(Posix, pipe2, "(I)[Ljava/io/FileDescriptor;"),
- NATIVE_METHOD(Posix, poll, "([Landroid/system/StructPollfd;I)I"),
- NATIVE_METHOD(Posix, posix_fallocate, "(Ljava/io/FileDescriptor;JJ)V"),
- NATIVE_METHOD(Posix, prctl, "(IJJJJ)I"),
- NATIVE_METHOD(Posix, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
- NATIVE_METHOD(Posix, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
- NATIVE_METHOD(Posix, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
- NATIVE_METHOD(Posix, readlink, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, realpath, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
- NATIVE_METHOD(Posix, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
- NATIVE_METHOD(Posix, remove, "(Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"),
- NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
- NATIVE_METHOD_OVERLOAD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress),
- NATIVE_METHOD(Posix, setegid, "(I)V"),
- NATIVE_METHOD(Posix, setenv, "(Ljava/lang/String;Ljava/lang/String;Z)V"),
- NATIVE_METHOD(Posix, seteuid, "(I)V"),
- NATIVE_METHOD(Posix, setgid, "(I)V"),
- NATIVE_METHOD(Posix, setpgid, "(II)V"),
- NATIVE_METHOD(Posix, setregid, "(II)V"),
- NATIVE_METHOD(Posix, setreuid, "(II)V"),
- NATIVE_METHOD(Posix, setsid, "()I"),
- NATIVE_METHOD(Posix, setsockoptByte, "(Ljava/io/FileDescriptor;III)V"),
- NATIVE_METHOD(Posix, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"),
- NATIVE_METHOD(Posix, setsockoptInt, "(Ljava/io/FileDescriptor;III)V"),
- NATIVE_METHOD(Posix, setsockoptIpMreqn, "(Ljava/io/FileDescriptor;III)V"),
- NATIVE_METHOD(Posix, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupReq;)V"),
- NATIVE_METHOD(Posix, setsockoptGroupSourceReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupSourceReq;)V"),
- NATIVE_METHOD(Posix, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"),
- NATIVE_METHOD(Posix, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"),
- NATIVE_METHOD(Posix, setuid, "(I)V"),
- NATIVE_METHOD(Posix, setxattr, "(Ljava/lang/String;Ljava/lang/String;[BI)V"),
- NATIVE_METHOD(Posix, shutdown, "(Ljava/io/FileDescriptor;I)V"),
- NATIVE_METHOD(Posix, socket, "(III)Ljava/io/FileDescriptor;"),
- NATIVE_METHOD(Posix, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"),
- NATIVE_METHOD(Posix, stat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
- NATIVE_METHOD(Posix, statvfs, "(Ljava/lang/String;)Landroid/system/StructStatVfs;"),
- NATIVE_METHOD(Posix, strerror, "(I)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, strsignal, "(I)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, symlink, "(Ljava/lang/String;Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, sysconf, "(I)J"),
- NATIVE_METHOD(Posix, tcdrain, "(Ljava/io/FileDescriptor;)V"),
- NATIVE_METHOD(Posix, tcsendbreak, "(Ljava/io/FileDescriptor;I)V"),
- NATIVE_METHOD(Posix, umaskImpl, "(I)I"),
- NATIVE_METHOD(Posix, uname, "()Landroid/system/StructUtsname;"),
- NATIVE_METHOD(Posix, unlink, "(Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, unsetenv, "(Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, waitpid, "(ILandroid/util/MutableInt;I)I"),
- NATIVE_METHOD(Posix, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
- NATIVE_METHOD(Posix, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
+ NATIVE_METHOD(Linux, accept, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(Linux, access, "(Ljava/lang/String;I)Z"),
+ NATIVE_METHOD(Linux, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
+ NATIVE_METHOD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
+ NATIVE_METHOD_OVERLOAD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
+ NATIVE_METHOD(Linux, capget,
+ "(Landroid/system/StructCapUserHeader;)[Landroid/system/StructCapUserData;"),
+ NATIVE_METHOD(Linux, capset,
+ "(Landroid/system/StructCapUserHeader;[Landroid/system/StructCapUserData;)V"),
+ NATIVE_METHOD(Linux, chmod, "(Ljava/lang/String;I)V"),
+ NATIVE_METHOD(Linux, chown, "(Ljava/lang/String;II)V"),
+ NATIVE_METHOD(Linux, close, "(Ljava/io/FileDescriptor;)V"),
+ NATIVE_METHOD(Linux, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
+ NATIVE_METHOD_OVERLOAD(Linux, connect, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
+ NATIVE_METHOD(Linux, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(Linux, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(Linux, environ, "()[Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, execv, "(Ljava/lang/String;[Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, execve, "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, fchmod, "(Ljava/io/FileDescriptor;I)V"),
+ NATIVE_METHOD(Linux, fchown, "(Ljava/io/FileDescriptor;II)V"),
+ NATIVE_METHOD(Linux, fcntlFlock, "(Ljava/io/FileDescriptor;ILandroid/system/StructFlock;)I"),
+ NATIVE_METHOD(Linux, fcntlInt, "(Ljava/io/FileDescriptor;II)I"),
+ NATIVE_METHOD(Linux, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"),
+ NATIVE_METHOD(Linux, fdatasync, "(Ljava/io/FileDescriptor;)V"),
+ NATIVE_METHOD(Linux, fstat, "(Ljava/io/FileDescriptor;)Landroid/system/StructStat;"),
+ NATIVE_METHOD(Linux, fstatvfs, "(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;"),
+ NATIVE_METHOD(Linux, fsync, "(Ljava/io/FileDescriptor;)V"),
+ NATIVE_METHOD(Linux, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
+ NATIVE_METHOD(Linux, gai_strerror, "(I)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, getegid, "()I"),
+ NATIVE_METHOD(Linux, geteuid, "()I"),
+ NATIVE_METHOD(Linux, getgid, "()I"),
+ NATIVE_METHOD(Linux, getenv, "(Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, getnameinfo, "(Ljava/net/InetAddress;I)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, getpeername, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
+ NATIVE_METHOD(Linux, getpgid, "(I)I"),
+ NATIVE_METHOD(Linux, getpid, "()I"),
+ NATIVE_METHOD(Linux, getppid, "()I"),
+ NATIVE_METHOD(Linux, getpwnam, "(Ljava/lang/String;)Landroid/system/StructPasswd;"),
+ NATIVE_METHOD(Linux, getpwuid, "(I)Landroid/system/StructPasswd;"),
+ NATIVE_METHOD(Linux, getsockname, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
+ NATIVE_METHOD(Linux, getsockoptByte, "(Ljava/io/FileDescriptor;II)I"),
+ NATIVE_METHOD(Linux, getsockoptInAddr, "(Ljava/io/FileDescriptor;II)Ljava/net/InetAddress;"),
+ NATIVE_METHOD(Linux, getsockoptInt, "(Ljava/io/FileDescriptor;II)I"),
+ NATIVE_METHOD(Linux, getsockoptLinger, "(Ljava/io/FileDescriptor;II)Landroid/system/StructLinger;"),
+ NATIVE_METHOD(Linux, getsockoptTimeval, "(Ljava/io/FileDescriptor;II)Landroid/system/StructTimeval;"),
+ NATIVE_METHOD(Linux, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"),
+ NATIVE_METHOD(Linux, gettid, "()I"),
+ NATIVE_METHOD(Linux, getuid, "()I"),
+ NATIVE_METHOD(Linux, getxattr, "(Ljava/lang/String;Ljava/lang/String;)[B"),
+ NATIVE_METHOD(Linux, getifaddrs, "()[Landroid/system/StructIfaddrs;"),
+ NATIVE_METHOD(Linux, if_indextoname, "(I)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, if_nametoindex, "(Ljava/lang/String;)I"),
+ NATIVE_METHOD(Linux, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
+ NATIVE_METHOD(Linux, ioctlFlags, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
+ NATIVE_METHOD(Linux, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
+ NATIVE_METHOD(Linux, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/util/MutableInt;)I"),
+ NATIVE_METHOD(Linux, ioctlMTU, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
+ NATIVE_METHOD(Linux, isatty, "(Ljava/io/FileDescriptor;)Z"),
+ NATIVE_METHOD(Linux, kill, "(II)V"),
+ NATIVE_METHOD(Linux, lchown, "(Ljava/lang/String;II)V"),
+ NATIVE_METHOD(Linux, link, "(Ljava/lang/String;Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, listen, "(Ljava/io/FileDescriptor;I)V"),
+ NATIVE_METHOD(Linux, listxattr, "(Ljava/lang/String;)[Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, lseek, "(Ljava/io/FileDescriptor;JI)J"),
+ NATIVE_METHOD(Linux, lstat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
+ NATIVE_METHOD(Linux, mincore, "(JJ[B)V"),
+ NATIVE_METHOD(Linux, mkdir, "(Ljava/lang/String;I)V"),
+ NATIVE_METHOD(Linux, mkfifo, "(Ljava/lang/String;I)V"),
+ NATIVE_METHOD(Linux, mlock, "(JJ)V"),
+ NATIVE_METHOD(Linux, mmap, "(JJIILjava/io/FileDescriptor;J)J"),
+ NATIVE_METHOD(Linux, msync, "(JJI)V"),
+ NATIVE_METHOD(Linux, munlock, "(JJ)V"),
+ NATIVE_METHOD(Linux, munmap, "(JJ)V"),
+ NATIVE_METHOD(Linux, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(Linux, pipe2, "(I)[Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(Linux, poll, "([Landroid/system/StructPollfd;I)I"),
+ NATIVE_METHOD(Linux, posix_fallocate, "(Ljava/io/FileDescriptor;JJ)V"),
+ NATIVE_METHOD(Linux, prctl, "(IJJJJ)I"),
+ NATIVE_METHOD(Linux, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
+ NATIVE_METHOD(Linux, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
+ NATIVE_METHOD(Linux, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
+ NATIVE_METHOD(Linux, readlink, "(Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, realpath, "(Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
+ NATIVE_METHOD(Linux, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
+ NATIVE_METHOD(Linux, remove, "(Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"),
+ NATIVE_METHOD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
+ NATIVE_METHOD_OVERLOAD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress),
+ NATIVE_METHOD(Linux, setegid, "(I)V"),
+ NATIVE_METHOD(Linux, setenv, "(Ljava/lang/String;Ljava/lang/String;Z)V"),
+ NATIVE_METHOD(Linux, seteuid, "(I)V"),
+ NATIVE_METHOD(Linux, setgid, "(I)V"),
+ NATIVE_METHOD(Linux, setpgid, "(II)V"),
+ NATIVE_METHOD(Linux, setregid, "(II)V"),
+ NATIVE_METHOD(Linux, setreuid, "(II)V"),
+ NATIVE_METHOD(Linux, setsid, "()I"),
+ NATIVE_METHOD(Linux, setsockoptByte, "(Ljava/io/FileDescriptor;III)V"),
+ NATIVE_METHOD(Linux, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"),
+ NATIVE_METHOD(Linux, setsockoptInt, "(Ljava/io/FileDescriptor;III)V"),
+ NATIVE_METHOD(Linux, setsockoptIpMreqn, "(Ljava/io/FileDescriptor;III)V"),
+ NATIVE_METHOD(Linux, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupReq;)V"),
+ NATIVE_METHOD(Linux, setsockoptGroupSourceReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupSourceReq;)V"),
+ NATIVE_METHOD(Linux, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"),
+ NATIVE_METHOD(Linux, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"),
+ NATIVE_METHOD(Linux, setuid, "(I)V"),
+ NATIVE_METHOD(Linux, setxattr, "(Ljava/lang/String;Ljava/lang/String;[BI)V"),
+ NATIVE_METHOD(Linux, shutdown, "(Ljava/io/FileDescriptor;I)V"),
+ NATIVE_METHOD(Linux, socket, "(III)Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(Linux, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"),
+ NATIVE_METHOD(Linux, stat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
+ NATIVE_METHOD(Linux, statvfs, "(Ljava/lang/String;)Landroid/system/StructStatVfs;"),
+ NATIVE_METHOD(Linux, strerror, "(I)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, strsignal, "(I)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, symlink, "(Ljava/lang/String;Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, sysconf, "(I)J"),
+ NATIVE_METHOD(Linux, tcdrain, "(Ljava/io/FileDescriptor;)V"),
+ NATIVE_METHOD(Linux, tcsendbreak, "(Ljava/io/FileDescriptor;I)V"),
+ NATIVE_METHOD(Linux, umaskImpl, "(I)I"),
+ NATIVE_METHOD(Linux, uname, "()Landroid/system/StructUtsname;"),
+ NATIVE_METHOD(Linux, unlink, "(Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, unsetenv, "(Ljava/lang/String;)V"),
+ NATIVE_METHOD(Linux, waitpid, "(ILandroid/util/MutableInt;I)I"),
+ NATIVE_METHOD(Linux, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
+ NATIVE_METHOD(Linux, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
};
-void register_libcore_io_Posix(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/io/Posix", gMethods, NELEM(gMethods));
+void register_libcore_io_Linux(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "libcore/io/Linux", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 803d818..0706ce8 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -21,8 +21,8 @@
libcore_icu_NativeConverter.cpp \
libcore_icu_TimeZoneNames.cpp \
libcore_io_AsynchronousCloseMonitor.cpp \
+ libcore_io_Linux.cpp \
libcore_io_Memory.cpp \
- libcore_io_Posix.cpp \
libcore_util_NativeAllocationRegistry.cpp \
org_apache_harmony_xml_ExpatParser.cpp \
sun_misc_Unsafe.cpp \
diff --git a/luni/src/test/java/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/io/BlockGuardOsTest.java
index 33eb411..567cf2d 100644
--- a/luni/src/test/java/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/io/BlockGuardOsTest.java
@@ -49,6 +49,8 @@
"android_getaddrinfo(java.lang.String,android.system.StructAddrinfo,int)",
"bind(java.io.FileDescriptor,java.net.InetAddress,int)",
"bind(java.io.FileDescriptor,java.net.SocketAddress)",
+ "capget(android.system.StructCapUserHeader)",
+ "capset(android.system.StructCapUserHeader,android.system.StructCapUserData[])",
"dup(java.io.FileDescriptor)",
"dup2(java.io.FileDescriptor,int)",
"environ()",
diff --git a/luni/src/test/java/libcore/java/lang/SystemTest.java b/luni/src/test/java/libcore/java/lang/SystemTest.java
index 2de659d..48f4591 100644
--- a/luni/src/test/java/libcore/java/lang/SystemTest.java
+++ b/luni/src/test/java/libcore/java/lang/SystemTest.java
@@ -16,17 +16,16 @@
package libcore.java.lang;
+import junit.framework.TestCase;
+
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.lang.SecurityException;
-import java.lang.SecurityManager;
import java.util.Formatter;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
-import junit.framework.TestCase;
public class SystemTest extends TestCase {
@@ -250,14 +249,4 @@
} catch (SecurityException expected) {
}
}
-
- // http://b/34867424
- public void testIcuPathIncludesTimeZoneOverride() {
- String icuDataPath = System.getProperty("android.icu.impl.ICUBinary.dataPath");
- String[] paths = icuDataPath.split(":");
- assertEquals(2, paths.length);
-
- assertTrue(paths[0].contains("/misc/zoneinfo/current/icu"));
- assertTrue(paths[1].contains("/usr/icu"));
- }
}
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index 566c314..3a14063 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -194,14 +194,6 @@
assertEquals(null, url.getRef());
}
- public void testAtSignInUserInfo() throws Exception {
- try {
- new URL("http://user@userhost.com:password@host");
- fail();
- } catch (MalformedURLException expected) {
- }
- }
-
public void testUserNoPassword() throws Exception {
URL url = new URL("http://user@host");
assertEquals("user@host", url.getAuthority());
@@ -762,4 +754,12 @@
assertEquals("/some/path", new URL("http://foobar.com/some/path#").getFile());
assertEquals("/some/path", new URL("http://foobar.com/some/path?#").getFile());
}
+
+ // http://b/33351987
+ public void testMultipleUserField() throws Exception {
+ final String host = "http://multiple@users@url.com";
+ URL url = new URL(host);
+ assertNull(url.getUserInfo());
+ assertTrue(url.getHost().isEmpty());
+ }
}
diff --git a/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java b/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java
index 564f7c9..dbbfeae 100644
--- a/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java
+++ b/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java
@@ -22,6 +22,7 @@
import org.junit.runner.RunWith;
import java.io.IOException;
+import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.NonReadableChannelException;
@@ -47,6 +48,7 @@
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -69,6 +71,7 @@
import static libcore.java.nio.file.FilesSetup.TEST_FILE_DATA_2;
import static libcore.java.nio.file.FilesSetup.readFromFile;
import static libcore.java.nio.file.FilesSetup.writeToFile;
+import static libcore.java.nio.file.LinuxFileSystemTestData.getPath_URI_InputOutputTestData;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
@@ -591,6 +594,55 @@
} catch (NullPointerException expected) {}
}
+ @Test
+ public void test_getPath() throws Exception {
+ List<LinuxFileSystemTestData.TestData> inputOutputTestCases = getPath_URI_InputOutputTestData();
+ for (LinuxFileSystemTestData.TestData inputOutputTestCase : inputOutputTestCases) {
+ assertEquals(inputOutputTestCase.output,
+ provider.getPath(new URI(inputOutputTestCase.input)).toString());
+ }
+
+ // When URI is null.
+ try {
+ provider.getPath(null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ // When Schema is not supported.
+ try {
+ provider.getPath(new URI("scheme://d"));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ @Test
+ public void test_getScheme() {
+ assertEquals("file", provider.getScheme());
+ }
+
+ @Test
+ public void test_installedProviders() {
+ assertNotNull(provider.installedProviders());
+ }
+
+ @Test
+ public void test_newFileSystem$URI$Map() throws Exception {
+ Path testPath = Paths.get("/");
+ assertNotNull(provider.getFileSystem(testPath.toUri()));
+
+ try {
+ provider.getFileSystem(null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ // Test the case when URI has illegal scheme.
+ URI stubURI = new URI("scheme://path");
+ try {
+ provider.getFileSystem(stubURI);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
String readFromFileChannel(FileChannel fc) throws IOException {
ByteBuffer bb = ByteBuffer.allocate(20);
fc.read(bb);
diff --git a/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java b/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java
new file mode 100644
index 0000000..bf6c6b7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java
@@ -0,0 +1,22 @@
+package libcore.java.nio.file.spi;
+
+import org.junit.Test;
+
+import java.nio.file.Paths;
+import java.nio.file.spi.FileTypeDetector;
+
+import static org.junit.Assert.assertEquals;
+
+public class FileTypeDetectorTest {
+
+ @Test
+ public void test_probeFileType() throws Exception {
+ FileTypeDetector defaultFileTypeDetector = sun.nio.fs.DefaultFileTypeDetector.create();
+ // The method uses file extensions to deduce mime type, therefore, it doesn't check for
+ // file existence.
+ assertEquals("text/plain",
+ defaultFileTypeDetector.probeContentType(Paths.get("file.txt")));
+ assertEquals("text/x-java",
+ defaultFileTypeDetector.probeContentType(Paths.get("file.java")));
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
index 4a5658c..cbaadd4 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
@@ -67,13 +67,21 @@
X509CertSelector certSelector = new X509CertSelector();
certSelector.addPathToName(GeneralName.iPAddress, "127.0.0.1");
+ // This constraint matches 127.0.0.1/255.255.255.255 aka 127.0.0.1
byte[] directMatch = { 127, 0, 0, 1, -1, -1, -1, -1 };
assertTrue(certSelector.match(newCertWithNameConstraint(directMatch, excluded)));
- byte[] noMatch = { 127, 0, 0, 2, -1, -1, -1, 127 };
+ // This constraint matches 127.0.0.2/255.255.255.255 aka 127.0.0.2
+ byte[] noMatch = { 127, 0, 0, 2, -1, -1, -1, -1 };
assertFalse(certSelector.match(newCertWithNameConstraint(noMatch, excluded)));
- // TODO: test that requires mask to match
+ // This constraint matches 127.0.0.0/255.255.255.255 aka 127.0.0.0
+ byte[] subnetWithNoMask = { 127, 0, 0, 0, -1, -1, -1, -1 };
+ assertFalse(certSelector.match(newCertWithNameConstraint(subnetWithNoMask, excluded)));
+
+ // This constraint matches 127.0.0.0/255.255.255.0 aka 127.0.0.0/24
+ byte[] maskedMatch = { 127, 0, 0, 0, -1, -1, -1, 0 };
+ assertTrue(certSelector.match(newCertWithNameConstraint(maskedMatch, excluded)));
}
public void testMatchMaskedIpv6NameConstraint() throws Exception {
@@ -84,19 +92,33 @@
X509CertSelector certSelector = new X509CertSelector();
certSelector.addPathToName(GeneralName.iPAddress, "1::1");
+ // This constraint matches 1::1/128 aka 1::1
byte[] directMatch = {
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
assertTrue(certSelector.match(newCertWithNameConstraint(directMatch, excluded)));
+ // This constraint matches 1::2/128 aka 1::2
byte[] noMatch = {
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
assertFalse(certSelector.match(newCertWithNameConstraint(noMatch, excluded)));
- // TODO: test that requires mask to match
+ // This constraint matches 1::/128 aka 1::
+ byte[] subnetWithNoMask = {
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+ assertFalse(certSelector.match(newCertWithNameConstraint(subnetWithNoMask, excluded)));
+
+ // This constraint matches 1::/120
+ byte[] maskedMatch = {
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ };
+ assertTrue(certSelector.match(newCertWithNameConstraint(maskedMatch, excluded)));
}
public void testMatchMalformedSubjectAlternativeName() throws Exception {
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index 1414c05..969402b 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -136,8 +136,6 @@
assertEquals("Palestine", new Locale("", "PS").getDisplayCountry(Locale.US));
assertEquals("Cocos (Keeling) Islands", new Locale("", "CC").getDisplayCountry(Locale.US));
- assertEquals("Congo (DRC)", new Locale("", "CD").getDisplayCountry(Locale.US));
- assertEquals("Congo (Republic)", new Locale("", "CG").getDisplayCountry(Locale.US));
assertEquals("Falkland Islands (Islas Malvinas)", new Locale("", "FK").getDisplayCountry(Locale.US));
assertEquals("Macedonia (FYROM)", new Locale("", "MK").getDisplayCountry(Locale.US));
assertEquals("Myanmar (Burma)", new Locale("", "MM").getDisplayCountry(Locale.US));
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index 6b692cf..375eb36 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -216,15 +216,26 @@
// http://b/7955614 and http://b/8026776.
public void testDisplayNames() throws Exception {
+ checkDisplayNames(Locale.US);
+ }
+
+ public void testDisplayNames_nonUS() throws Exception {
+ // run checkDisplayNames with an arbitrary set of Locales.
+ checkDisplayNames(Locale.CHINESE);
+ checkDisplayNames(Locale.FRENCH);
+ checkDisplayNames(Locale.forLanguageTag("bn-BD"));
+ }
+
+ public void checkDisplayNames(Locale locale) throws Exception {
// Check that there are no time zones that use DST but have the same display name for
// both standard and daylight time.
StringBuilder failures = new StringBuilder();
for (String id : TimeZone.getAvailableIDs()) {
TimeZone tz = TimeZone.getTimeZone(id);
- String longDst = tz.getDisplayName(true, TimeZone.LONG, Locale.US);
- String longStd = tz.getDisplayName(false, TimeZone.LONG, Locale.US);
- String shortDst = tz.getDisplayName(true, TimeZone.SHORT, Locale.US);
- String shortStd = tz.getDisplayName(false, TimeZone.SHORT, Locale.US);
+ String longDst = tz.getDisplayName(true, TimeZone.LONG, locale);
+ String longStd = tz.getDisplayName(false, TimeZone.LONG, locale);
+ String shortDst = tz.getDisplayName(true, TimeZone.SHORT, locale);
+ String shortStd = tz.getDisplayName(false, TimeZone.SHORT, locale);
if (tz.useDaylightTime()) {
// The long std and dst strings must differ!
@@ -329,15 +340,6 @@
return String.format("GMT%c%02d:%02d", sign, offset / 60, offset % 60);
}
- public void testAllDisplayNames() throws Exception {
- for (Locale locale : Locale.getAvailableLocales()) {
- for (String id : TimeZone.getAvailableIDs()) {
- TimeZone tz = TimeZone.getTimeZone(id);
- assertNotNull(tz.getDisplayName(false, TimeZone.LONG, locale));
- }
- }
- }
-
// http://b/18839557
public void testOverflowing32BitUnixDates() {
final TimeZone tz = TimeZone.getTimeZone("America/New_York");
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherOutputStreamTest.java b/luni/src/test/java/libcore/javax/crypto/CipherOutputStreamTest.java
new file mode 100644
index 0000000..dd9a9a0
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/CipherOutputStreamTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.crypto;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.AEADBadTagException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+public final class CipherOutputStreamTest extends TestCase {
+
+ // From b/36636576. CipherOutputStream had a bug where it would ignore exceptions
+ // thrown during close().
+ public void testDecryptCorruptGCM() throws Exception {
+ for (Provider provider : Security.getProviders()) {
+ Cipher cipher;
+ try {
+ cipher = Cipher.getInstance("AES/GCM/NoPadding", provider);
+ } catch (NoSuchAlgorithmException e) {
+ continue;
+ }
+ SecretKey key;
+ if (provider.getName().equals("AndroidKeyStoreBCWorkaround")) {
+ key = getAndroidKeyStoreSecretKey();
+ } else {
+ KeyGenerator keygen = KeyGenerator.getInstance("AES");
+ keygen.init(256);
+ key = keygen.generateKey();
+ }
+ GCMParameterSpec params = new GCMParameterSpec(128, new byte[12]);
+ byte[] unencrypted = new byte[200];
+
+ // Normal providers require specifying the IV, but KeyStore prohibits it, so
+ // we have to special-case it
+ if (provider.getName().equals("AndroidKeyStoreBCWorkaround")) {
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ } else {
+ cipher.init(Cipher.ENCRYPT_MODE, key, params);
+ }
+ byte[] encrypted = cipher.doFinal(unencrypted);
+
+ // Corrupt the final byte, which will corrupt the authentication tag
+ encrypted[encrypted.length - 1] ^= 1;
+
+ cipher.init(Cipher.DECRYPT_MODE, key, params);
+ CipherOutputStream cos = new CipherOutputStream(new ByteArrayOutputStream(), cipher);
+ try {
+ cos.write(encrypted);
+ cos.close();
+ fail("Writing a corrupted stream should throw an exception."
+ + " Provider: " + provider);
+ } catch (IOException expected) {
+ assertTrue(expected.getCause() instanceof AEADBadTagException);
+ }
+ }
+
+ }
+
+ // The AndroidKeyStoreBCWorkaround provider can't use keys created by anything
+ // but Android KeyStore, which requires using its own parameters class to create
+ // keys. Since we're in javax, we can't link against the frameworks classes, so
+ // we have to use reflection to make a suitable key. This will always be safe
+ // because if we're making a key for AndroidKeyStoreBCWorkaround, the KeyStore
+ // classes must be present.
+ private static SecretKey getAndroidKeyStoreSecretKey() throws Exception {
+ KeyGenerator keygen = KeyGenerator.getInstance("AES", "AndroidKeyStore");
+ Class<?> keyParamsBuilderClass = keygen.getClass().getClassLoader().loadClass(
+ "android.security.keystore.KeyGenParameterSpec$Builder");
+ Object keyParamsBuilder = keyParamsBuilderClass.getConstructor(String.class, Integer.TYPE)
+ // 3 is PURPOSE_ENCRYPT | PURPOSE_DECRYPT
+ .newInstance("testDecryptCorruptGCM", 3);
+ keyParamsBuilderClass.getMethod("setBlockModes", new Class[]{String[].class})
+ .invoke(keyParamsBuilder, new Object[]{new String[]{"GCM"}});
+ keyParamsBuilderClass.getMethod("setEncryptionPaddings", new Class[]{String[].class})
+ .invoke(keyParamsBuilder, new Object[]{new String[]{"NoPadding"}});
+ AlgorithmParameterSpec spec = (AlgorithmParameterSpec)
+ keyParamsBuilderClass.getMethod("build", new Class[]{}).invoke(keyParamsBuilder);
+ keygen.init(spec);
+ return keygen.generateKey();
+ }
+}
diff --git a/luni/src/test/java/libcore/util/TimeZoneDataFilesTest.java b/luni/src/test/java/libcore/util/TimeZoneDataFilesTest.java
new file mode 100644
index 0000000..efba900
--- /dev/null
+++ b/luni/src/test/java/libcore/util/TimeZoneDataFilesTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TimeZoneDataFilesTest {
+
+ @Test
+ public void getTimeZoneFilePaths() {
+ String[] paths = TimeZoneDataFiles.getTimeZoneFilePaths("foo");
+ assertEquals(2, paths.length);
+
+ assertTrue(paths[0].contains("/misc/zoneinfo/current/"));
+ assertTrue(paths[0].endsWith("foo"));
+
+ assertTrue(paths[1].contains("/usr/share/zoneinfo/"));
+ assertTrue(paths[1].endsWith("foo"));
+ }
+
+ // http://b/34867424
+ @Test
+ public void generateIcuDataPath_includesTimeZoneOverride() {
+ String icuDataPath = System.getProperty("android.icu.impl.ICUBinary.dataPath");
+ assertEquals(icuDataPath, TimeZoneDataFiles.generateIcuDataPath());
+
+ String[] paths = icuDataPath.split(":");
+ assertEquals(2, paths.length);
+
+ assertTrue(paths[0].contains("/misc/zoneinfo/current/icu"));
+ assertTrue(paths[1].contains("/usr/icu"));
+ }
+}
diff --git a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
index 901519e..e6ec4df 100644
--- a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
+++ b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
@@ -28,27 +28,27 @@
public class ZoneInfoDBTest extends junit.framework.TestCase {
// The base tzdata file, always present on a device.
- private static final String TZDATA_IN_ROOT =
- System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata";
+ private static final String SYSTEM_TZDATA_FILE =
+ TimeZoneDataFiles.getSystemTimeZoneFile(ZoneInfoDB.TZDATA_FILE);
// An empty override file should fall back to the default file.
public void testLoadTzDataWithFallback_emptyOverrideFile() throws Exception {
- ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
String emptyFilePath = makeEmptyFile().getPath();
ZoneInfoDB.TzData dataWithEmptyOverride =
- ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath, TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath, SYSTEM_TZDATA_FILE);
assertEquals(data.getVersion(), dataWithEmptyOverride.getVersion());
assertEquals(data.getAvailableIDs().length, dataWithEmptyOverride.getAvailableIDs().length);
}
// A corrupt override file should fall back to the default file.
public void testLoadTzDataWithFallback_corruptOverrideFile() throws Exception {
- ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
String corruptFilePath = makeCorruptFile().getPath();
ZoneInfoDB.TzData dataWithCorruptOverride =
- ZoneInfoDB.TzData.loadTzDataWithFallback(corruptFilePath, TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData.loadTzDataWithFallback(corruptFilePath, SYSTEM_TZDATA_FILE);
assertEquals(data.getVersion(), dataWithCorruptOverride.getVersion());
assertEquals(data.getAvailableIDs().length, dataWithCorruptOverride.getAvailableIDs().length);
}
@@ -64,7 +64,7 @@
// Given a valid override file, we should find ourselves using that.
public void testLoadTzDataWithFallback_goodOverrideFile() throws Exception {
- RandomAccessFile in = new RandomAccessFile(TZDATA_IN_ROOT, "r");
+ RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
byte[] content = new byte[(int) in.length()];
in.readFully(content);
in.close();
@@ -79,9 +79,9 @@
File goodFile = makeTemporaryFile(content);
try {
ZoneInfoDB.TzData dataWithOverride =
- ZoneInfoDB.TzData.loadTzDataWithFallback(goodFile.getPath(), TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData.loadTzDataWithFallback(goodFile.getPath(), SYSTEM_TZDATA_FILE);
assertEquals("9999z", dataWithOverride.getVersion());
- ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
assertEquals(data.getAvailableIDs().length, dataWithOverride.getAvailableIDs().length);
} finally {
goodFile.delete();
@@ -89,7 +89,7 @@
}
public void testLoadTzData_badHeader() throws Exception {
- RandomAccessFile in = new RandomAccessFile(TZDATA_IN_ROOT, "r");
+ RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
byte[] content = new byte[(int) in.length()];
in.readFully(content);
in.close();
@@ -212,7 +212,7 @@
// Confirms any caching that exists correctly handles TimeZone mutability.
public void testMakeTimeZone_timeZoneMutability() throws Exception {
- ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
String tzId = "Europe/London";
ZoneInfo first = data.makeTimeZone(tzId);
ZoneInfo second = data.makeTimeZone(tzId);
@@ -229,21 +229,21 @@
}
public void testMakeTimeZone_notFound() throws Exception {
- ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
assertNull(data.makeTimeZone("THIS_TZ_DOES_NOT_EXIST"));
assertFalse(data.hasTimeZone("THIS_TZ_DOES_NOT_EXIST"));
}
public void testMakeTimeZone_found() throws Exception {
- ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
assertNotNull(data.makeTimeZone("Europe/London"));
assertTrue(data.hasTimeZone("Europe/London"));
}
public void testGetRulesVersion() throws Exception {
- ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
- String rulesVersion = ZoneInfoDB.TzData.getRulesVersion(new File(TZDATA_IN_ROOT));
+ String rulesVersion = ZoneInfoDB.TzData.getRulesVersion(new File(SYSTEM_TZDATA_FILE));
assertEquals(data.getVersion(), rulesVersion);
}
diff --git a/non_openjdk_java_files.mk b/non_openjdk_java_files.mk
index 9d59a4a..31ee139 100644
--- a/non_openjdk_java_files.mk
+++ b/non_openjdk_java_files.mk
@@ -6,6 +6,8 @@
luni/src/main/java/android/system/OsConstants.java \
luni/src/main/java/android/system/PacketSocketAddress.java \
luni/src/main/java/android/system/StructAddrinfo.java \
+ luni/src/main/java/android/system/StructCapUserData.java \
+ luni/src/main/java/android/system/StructCapUserHeader.java \
luni/src/main/java/android/system/StructFlock.java \
luni/src/main/java/android/system/StructGroupReq.java \
luni/src/main/java/android/system/StructGroupSourceReq.java \
@@ -235,31 +237,6 @@
xml/src/main/java/org/xmlpull/v1/sax2/Driver.java \
non_openjdk_java_files := \
- dex/src/main/java/com/android/dex/Annotation.java \
- dex/src/main/java/com/android/dex/ClassData.java \
- dex/src/main/java/com/android/dex/ClassDef.java \
- dex/src/main/java/com/android/dex/Code.java \
- dex/src/main/java/com/android/dex/Dex.java \
- dex/src/main/java/com/android/dex/DexException.java \
- dex/src/main/java/com/android/dex/DexFormat.java \
- dex/src/main/java/com/android/dex/DexIndexOverflowException.java \
- dex/src/main/java/com/android/dex/EncodedValue.java \
- dex/src/main/java/com/android/dex/EncodedValueCodec.java \
- dex/src/main/java/com/android/dex/EncodedValueReader.java \
- dex/src/main/java/com/android/dex/FieldId.java \
- dex/src/main/java/com/android/dex/Leb128.java \
- dex/src/main/java/com/android/dex/MethodId.java \
- dex/src/main/java/com/android/dex/Mutf8.java \
- dex/src/main/java/com/android/dex/ProtoId.java \
- dex/src/main/java/com/android/dex/SizeOf.java \
- dex/src/main/java/com/android/dex/TableOfContents.java \
- dex/src/main/java/com/android/dex/TypeList.java \
- dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java \
- dex/src/main/java/com/android/dex/util/ByteInput.java \
- dex/src/main/java/com/android/dex/util/ByteOutput.java \
- dex/src/main/java/com/android/dex/util/ExceptionWithContext.java \
- dex/src/main/java/com/android/dex/util/FileUtils.java \
- dex/src/main/java/com/android/dex/util/Unsigned.java \
dalvik/src/main/java/dalvik/system/profiler/AsciiHprofWriter.java \
dalvik/src/main/java/dalvik/system/profiler/BinaryHprof.java \
dalvik/src/main/java/dalvik/system/profiler/BinaryHprofReader.java \
@@ -294,11 +271,11 @@
luni/src/main/java/libcore/io/IoTracker.java \
luni/src/main/java/libcore/io/IoUtils.java \
luni/src/main/java/libcore/io/Libcore.java \
+ luni/src/main/java/libcore/io/Linux.java \
luni/src/main/java/libcore/io/Memory.java \
luni/src/main/java/libcore/io/MemoryMappedFile.java \
luni/src/main/java/libcore/io/NioBufferIterator.java \
luni/src/main/java/libcore/io/Os.java \
- luni/src/main/java/libcore/io/Posix.java \
luni/src/main/java/libcore/io/SizeOf.java \
luni/src/main/java/libcore/io/Streams.java \
luni/src/main/java/libcore/math/MathUtils.java \
@@ -330,6 +307,7 @@
luni/src/main/java/libcore/util/Objects.java \
luni/src/main/java/libcore/util/RecoverySystem.java \
luni/src/main/java/libcore/util/SneakyThrow.java \
+ luni/src/main/java/libcore/util/TimeZoneDataFiles.java \
luni/src/main/java/libcore/util/ZoneInfo.java \
luni/src/main/java/libcore/util/ZoneInfoDB.java \
luni/src/main/java/libcore/util/HexEncoding.java \
diff --git a/ojluni/src/main/java/java/awt/font/NumericShaper.java b/ojluni/src/main/java/java/awt/font/NumericShaper.java
index c8100bf..7e1980e 100644
--- a/ojluni/src/main/java/java/awt/font/NumericShaper.java
+++ b/ojluni/src/main/java/java/awt/font/NumericShaper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -633,7 +633,6 @@
0x06d6, 0x06e5,
0x06e7, 0x06ee,
0x06f0, 0x06fa,
- 0x070f, 0x0710,
0x0711, 0x0712,
0x0730, 0x074d,
0x07a6, 0x07b1,
@@ -644,7 +643,7 @@
0x0825, 0x0828,
0x0829, 0x0830,
0x0859, 0x085e,
- 0x0900, 0x0903,
+ 0x08e4, 0x0903,
0x093a, 0x093b,
0x093c, 0x093d,
0x0941, 0x0949,
@@ -723,6 +722,7 @@
0x1732, 0x1735,
0x1752, 0x1760,
0x1772, 0x1780,
+ 0x17b4, 0x17b6,
0x17b7, 0x17be,
0x17c6, 0x17c7,
0x17c9, 0x17d4,
@@ -750,6 +750,7 @@
0x1b80, 0x1b82,
0x1ba2, 0x1ba6,
0x1ba8, 0x1baa,
+ 0x1bab, 0x1bac,
0x1be6, 0x1be7,
0x1be8, 0x1bea,
0x1bed, 0x1bee,
@@ -760,6 +761,7 @@
0x1cd4, 0x1ce1,
0x1ce2, 0x1ce9,
0x1ced, 0x1cee,
+ 0x1cf4, 0x1cf5,
0x1dc0, 0x1e00,
0x1fbd, 0x1fbe,
0x1fbf, 0x1fc2,
@@ -791,7 +793,8 @@
0x26ad, 0x2800,
0x2900, 0x2c00,
0x2ce5, 0x2ceb,
- 0x2cef, 0x2d00,
+ 0x2cef, 0x2cf2,
+ 0x2cf9, 0x2d00,
0x2d7f, 0x2d80,
0x2de0, 0x3005,
0x3008, 0x3021,
@@ -814,6 +817,7 @@
0xa490, 0xa4d0,
0xa60d, 0xa610,
0xa66f, 0xa680,
+ 0xa69f, 0xa6a0,
0xa6f0, 0xa6f2,
0xa700, 0xa722,
0xa788, 0xa789,
@@ -842,6 +846,8 @@
0xaab7, 0xaab9,
0xaabe, 0xaac0,
0xaac1, 0xaac2,
+ 0xaaec, 0xaaee,
+ 0xaaf6, 0xab01,
0xabe5, 0xabe6,
0xabe8, 0xabe9,
0xabed, 0xabf0,
@@ -867,6 +873,16 @@
0x11080, 0x11082,
0x110b3, 0x110b7,
0x110b9, 0x110bb,
+ 0x11100, 0x11103,
+ 0x11127, 0x1112c,
+ 0x1112d, 0x11136,
+ 0x11180, 0x11182,
+ 0x111b6, 0x111bf,
+ 0x116ab, 0x116ac,
+ 0x116ad, 0x116ae,
+ 0x116b0, 0x116b6,
+ 0x116b7, 0x116c0,
+ 0x16f8f, 0x16f93,
0x1d167, 0x1d16a,
0x1d173, 0x1d183,
0x1d185, 0x1d18c,
@@ -877,7 +893,9 @@
0x1d74f, 0x1d750,
0x1d789, 0x1d78a,
0x1d7c3, 0x1d7c4,
- 0x1d7ce, 0x1f110,
+ 0x1d7ce, 0x1ee00,
+ 0x1eef0, 0x1f110,
+ 0x1f16a, 0x1f170,
0x1f300, 0x1f48c,
0x1f48d, 0x1f524,
0x1f525, 0x20000,
@@ -1194,7 +1212,7 @@
* For example, to check if a shaper shapes to Arabic, you would use the
* following:
* <blockquote>
- * <code>if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... </code>
+ * {@code if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... }
* </blockquote>
*
* <p>Note that this method supports only the bit mask-based
diff --git a/ojluni/src/main/java/java/beans/ChangeListenerMap.java b/ojluni/src/main/java/java/beans/ChangeListenerMap.java
index fead0a4..fa8be47 100644
--- a/ojluni/src/main/java/java/beans/ChangeListenerMap.java
+++ b/ojluni/src/main/java/java/beans/ChangeListenerMap.java
@@ -76,7 +76,7 @@
*/
public final synchronized void add(String name, L listener) {
if (this.map == null) {
- this.map = new HashMap<String, L[]>();
+ this.map = new HashMap<>();
}
L[] array = this.map.get(name);
int size = (array != null)
@@ -146,7 +146,7 @@
public final void set(String name, L[] listeners) {
if (listeners != null) {
if (this.map == null) {
- this.map = new HashMap<String, L[]>();
+ this.map = new HashMap<>();
}
this.map.put(name, listeners);
}
@@ -167,7 +167,7 @@
if (this.map == null) {
return newArray(0);
}
- List<L> list = new ArrayList<L>();
+ List<L> list = new ArrayList<>();
L[] listeners = this.map.get(null);
if (listeners != null) {
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeEvent.java b/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
index 55397ef..eeaa651 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package java.beans;
+import java.util.EventObject;
+
/**
* A "PropertyChange" event gets delivered whenever a bean changes a "bound"
* or "constrained" property. A PropertyChangeEvent object is sent as an
@@ -42,21 +44,21 @@
* arbitrary set of if its properties have changed. In this case the
* old and new values should also be null.
*/
-
-public class PropertyChangeEvent extends java.util.EventObject {
+public class PropertyChangeEvent extends EventObject {
private static final long serialVersionUID = 7042693688939648123L;
/**
- * Constructs a new <code>PropertyChangeEvent</code>.
+ * Constructs a new {@code PropertyChangeEvent}.
*
- * @param source The bean that fired the event.
- * @param propertyName The programmatic name of the property
- * that was changed.
- * @param oldValue The old value of the property.
- * @param newValue The new value of the property.
+ * @param source the bean that fired the event
+ * @param propertyName the programmatic name of the property that was changed
+ * @param oldValue the old value of the property
+ * @param newValue the new value of the property
+ *
+ * @throws IllegalArgumentException if {@code source} is {@code null}
*/
public PropertyChangeEvent(Object source, String propertyName,
- Object oldValue, Object newValue) {
+ Object oldValue, Object newValue) {
super(source);
this.propertyName = propertyName;
this.newValue = newValue;
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
index 270912c..d55ae76 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,7 +156,7 @@
* <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
* the parameter.
*
- * <pre>
+ * <pre>{@code
* PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
* for (int i = 0; i < listeners.length; i++) {
* if (listeners[i] instanceof PropertyChangeListenerProxy) {
@@ -168,7 +168,7 @@
* }
* }
* }
- *</pre>
+ * }</pre>
*
* @see PropertyChangeListenerProxy
* @return all of the <code>PropertyChangeListeners</code> added or an
@@ -431,7 +431,7 @@
listeners = entry.getValue();
} else {
if (children == null) {
- children = new Hashtable<String, PropertyChangeSupport>();
+ children = new Hashtable<>();
}
PropertyChangeSupport pcs = new PropertyChangeSupport(this.source);
pcs.map.set(null, entry.getValue());
@@ -460,6 +460,7 @@
ObjectInputStream.GetField fields = s.readFields();
+ @SuppressWarnings("unchecked")
Hashtable<String, PropertyChangeSupport> children = (Hashtable<String, PropertyChangeSupport>) fields.get("children", null);
this.source = fields.get("source", null);
fields.get("propertyChangeSupportSerializedDataVersion", 2);
diff --git a/ojluni/src/main/java/java/lang/Class.java b/ojluni/src/main/java/java/lang/Class.java
index 8591bfe..3717cd7 100644
--- a/ojluni/src/main/java/java/lang/Class.java
+++ b/ojluni/src/main/java/java/lang/Class.java
@@ -27,7 +27,6 @@
package java.lang;
import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
import java.io.InputStream;
import java.io.Serializable;
@@ -128,7 +127,7 @@
* DexCache of resolved constant pool entries. Will be null for certain runtime-generated classes
* e.g. arrays and primitive classes.
*/
- private transient DexCache dexCache;
+ private transient Object dexCache;
/**
* Extra data that only some classes possess. This is allocated lazily as needed.
@@ -960,24 +959,19 @@
public Class<?>[] getInterfaces() {
if (isArray()) {
return new Class<?>[] { Cloneable.class, Serializable.class };
- } else if (isProxy()) {
- return getProxyInterfaces();
}
- Dex dex = getDex();
- if (dex == null) {
+
+ final Class<?>[] ifaces = getInterfacesInternal();
+ if (ifaces == null) {
return EmptyArray.CLASS;
}
- short[] interfaces = dex.interfaceTypeIndicesFromClassDefIndex(dexClassDefIndex);
- Class<?>[] result = new Class<?>[interfaces.length];
- for (int i = 0; i < interfaces.length; i++) {
- result[i] = getDexCacheType(dex, interfaces[i]);
- }
- return result;
+
+ return ifaces;
}
- // Returns the interfaces that this proxy class directly implements.
@FastNative
- private native Class<?>[] getProxyInterfaces();
+ private native Class<?>[] getInterfacesInternal();
+
/**
* Returns the {@code Type}s representing the interfaces
@@ -2637,70 +2631,6 @@
}
/**
- * Returns the dex file from which this class was loaded.
- *
- * @hide
- */
- public Dex getDex() {
- if (dexCache == null) {
- return null;
- }
- return dexCache.getDex();
- }
- /**
- * Returns a string from the dex cache, computing the string from the dex file if necessary.
- *
- * @hide
- */
- public String getDexCacheString(Dex dex, int dexStringIndex) {
- String s = dexCache.getResolvedString(dexStringIndex);
- if (s == null) {
- s = dex.strings().get(dexStringIndex).intern();
- dexCache.setResolvedString(dexStringIndex, s);
- }
- return s;
- }
-
- /**
- * Returns a resolved type from the dex cache, computing the type from the dex file if
- * necessary.
- *
- * @hide
- */
- public Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
- Class<?> resolvedType = dexCache.getResolvedType(dexTypeIndex);
- if (resolvedType == null) {
-
- // Temporary debugging code for issue b/35970927. In the absence of reproducibility,
- // we want more information on :
- //
- // (a) This class: a proxy for the dex file whose cache is being queried.
- // (b) The dex type index & descriptor index.
- // (c) The resolved descriptor.
- // (d) The wrapper message : this is the name of the class used by InternalNames
- // for its loadClass call.
- //
- // (c) & (d) should help us rule out string compression issues.
- // (a) & (b) should help us rule out some classes of heap corruption issues.
- int descriptorIndex = 0;
- String descriptor = "";
- try {
- descriptorIndex = dex.typeIds().get(dexTypeIndex);
- descriptor = getDexCacheString(dex, descriptorIndex);
- resolvedType = InternalNames.getClass(getClassLoader(), descriptor);
- } catch (NoClassDefFoundError error) {
- throw new NoClassDefFoundError("class: " + getName()
- + ", dexTypeIndex=" + dexTypeIndex
- + ", descriptorIndex=" + descriptorIndex + ", desc=" + descriptor
- + ", wrapped Msg= " + error.getMessage());
- }
-
- dexCache.setResolvedType(dexTypeIndex, resolvedType);
- }
- return resolvedType;
- }
-
- /**
* @hide
*/
public int getAccessFlags() {
diff --git a/ojluni/src/main/java/java/lang/ClassLoader.java b/ojluni/src/main/java/java/lang/ClassLoader.java
index 9a34a34..8b9d27d 100644
--- a/ojluni/src/main/java/java/lang/ClassLoader.java
+++ b/ojluni/src/main/java/java/lang/ClassLoader.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -160,7 +160,7 @@
* }
* </pre></blockquote>
*
- * <h4> <a name="name">Binary names</a> </h4>
+ * <h3> <a name="name">Binary names</a> </h3>
*
* <p> Any class name provided as a {@link String} parameter to methods in
* <tt>ClassLoader</tt> must be a binary name as defined by
@@ -298,7 +298,7 @@
* #loadClass(String, boolean)} method. It is invoked by the Java virtual
* machine to resolve class references. Invoking this method is equivalent
* to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
- * false)</tt>}. </p>
+ * false)</tt>}.
*
* @param name
* The <a href="#name">binary name</a> of the class
@@ -317,7 +317,7 @@
* default implementation of this method searches for classes in the
* following order:
*
- * <p><ol>
+ * <ol>
*
* <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
* has already been loaded. </p></li>
@@ -360,7 +360,7 @@
throws ClassNotFoundException
{
// First, check if the class has already been loaded
- Class c = findLoadedClass(name);
+ Class<?> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
@@ -389,7 +389,7 @@
* follow the delegation model for loading classes, and will be invoked by
* the {@link #loadClass <tt>loadClass</tt>} method after checking the
* parent class loader for the requested class. The default implementation
- * throws a <tt>ClassNotFoundException</tt>. </p>
+ * throws a <tt>ClassNotFoundException</tt>.
*
* @param name
* The <a href="#name">binary name</a> of the class
@@ -542,7 +542,7 @@
* bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it
* must be equal to the <a href="#name">binary name</a> of the class
* specified by the byte array "<tt>b</tt>", otherwise a {@link
- * NoClassDefFoundError} will be thrown. </p>
+ * NoClassDefFoundError <tt>NoClassDefFoundError</tt>} will be thrown. </p>
*
* @param name
* The expected <a href="#name">binary name</a> of the class, or
@@ -609,16 +609,16 @@
* <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
* result as the statements
*
- * <blockquote><tt>
+ *<p> <tt>
* ...<br>
- * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link
+ * byte[] temp = new byte[bBuffer.{@link
* java.nio.ByteBuffer#remaining remaining}()];<br>
- * </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
+ * bBuffer.{@link java.nio.ByteBuffer#get(byte[])
* get}(temp);<br>
* return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
- * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0,
- * temp.length, </tt><i>pd</i><tt>);<br>
- * </tt></blockquote>
+ * cl.defineClass}(name, temp, 0,
+ * temp.length, pd);<br>
+ * </tt></p>
*
* @param name
* The expected <a href="#name">binary name</a>. of the class, or
@@ -666,7 +666,6 @@
* already been linked, then this method simply returns. Otherwise, the
* class is linked as described in the "Execution" chapter of
* <cite>The Java™ Language Specification</cite>.
- * </p>
*
* @param c
* The class to link
@@ -711,7 +710,7 @@
* Returns a class loaded by the bootstrap class loader;
* or return null if not found.
*/
- private Class findBootstrapClassOrNull(String name)
+ private Class<?> findBootstrapClassOrNull(String name)
{
return null;
}
@@ -720,7 +719,7 @@
* Returns the class with the given <a href="#name">binary name</a> if this
* loader has been recorded by the Java virtual machine as an initiating
* loader of a class with that <a href="#name">binary name</a>. Otherwise
- * <tt>null</tt> is returned. </p>
+ * <tt>null</tt> is returned.
*
* @param name
* The <a href="#name">binary name</a> of the class
@@ -741,7 +740,7 @@
/**
* Sets the signers of a class. This should be invoked after defining a
- * class. </p>
+ * class.
*
* @param c
* The <tt>Class</tt> object
@@ -770,6 +769,10 @@
* built-in to the virtual machine is searched. That failing, this method
* will invoke {@link #findResource(String)} to find the resource. </p>
*
+ * @apiNote When overriding this method it is recommended that an
+ * implementation ensures that any delegation is consistent with the {@link
+ * #getResources(java.lang.String) getResources(String)} method.
+ *
* @param name
* The resource name
*
@@ -803,6 +806,13 @@
* <p> The search order is described in the documentation for {@link
* #getResource(String)}. </p>
*
+ * @apiNote When overriding this method it is recommended that an
+ * implementation ensures that any delegation is consistent with the {@link
+ * #getResource(java.lang.String) getResource(String)} method. This should
+ * ensure that the first element returned by the Enumeration's
+ * {@code nextElement} method is the same resource that the
+ * {@code getResource(String)} method would return.
+ *
* @param name
* The resource name
*
@@ -819,7 +829,8 @@
* @since 1.2
*/
public Enumeration<URL> getResources(String name) throws IOException {
- Enumeration[] tmp = new Enumeration[2];
+ @SuppressWarnings("unchecked")
+ Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
if (parent != null) {
tmp[0] = parent.getResources(name);
} else {
@@ -832,7 +843,7 @@
/**
* Finds the resource with the given name. Class loader implementations
- * should override this method to specify where to find resources. </p>
+ * should override this method to specify where to find resources.
*
* @param name
* The resource name
@@ -850,7 +861,7 @@
* Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
* representing all the resources with the given name. Class loader
* implementations should override this method to specify where to load
- * resources from. </p>
+ * resources from.
*
* @param name
* The resource name
@@ -868,14 +879,16 @@
}
/**
- * Registers the caller as parallel capable.</p>
+ * Registers the caller as parallel capable.
* The registration succeeds if and only if all of the following
- * conditions are met: <br>
- * 1. no instance of the caller has been created</p>
- * 2. all of the super classes (except class Object) of the caller are
- * registered as parallel capable</p>
- * Note that once a class loader is registered as parallel capable, there
- * is no way to change it back. </p>
+ * conditions are met:
+ * <ol>
+ * <li> no instance of the caller has been created</li>
+ * <li> all of the super classes (except class Object) of the caller are
+ * registered as parallel capable</li>
+ * </ol>
+ * <p>Note that once a class loader is registered as parallel capable, there
+ * is no way to change it back.</p>
*
* @return true if the caller is successfully registered as
* parallel capable and false if otherwise.
@@ -890,7 +903,7 @@
/**
* Find a resource of the specified name from the search path used to load
* classes. This method locates the resource through the system class
- * loader (see {@link #getSystemClassLoader()}). </p>
+ * loader (see {@link #getSystemClassLoader()}).
*
* @param name
* The resource name
@@ -982,7 +995,7 @@
/**
* Open for reading, a resource of the specified name from the search path
* used to load classes. This method locates the resource through the
- * system class loader (see {@link #getSystemClassLoader()}). </p>
+ * system class loader (see {@link #getSystemClassLoader()}).
*
* @param name
* The resource name
@@ -1101,7 +1114,7 @@
* class loaders to define the packages for their classes. Packages must
* be created before the class is defined, and package names must be
* unique within a class loader and cannot be redefined or changed once
- * created. </p>
+ * created.
*
* @param name
* The package name
@@ -1158,7 +1171,7 @@
/**
* Returns a <tt>Package</tt> that has been defined by this class loader
- * or any of its ancestors. </p>
+ * or any of its ancestors.
*
* @param name
* The package name
@@ -1178,7 +1191,7 @@
/**
* Returns all of the <tt>Packages</tt> defined by this class loader and
- * its ancestors. </p>
+ * its ancestors.
*
* @return The array of <tt>Package</tt> objects defined by this
* <tt>ClassLoader</tt>
@@ -1202,7 +1215,7 @@
* method to locate the native libraries that belong to classes loaded with
* this class loader. If this method returns <tt>null</tt>, the VM
* searches the library along the path specified as the
- * "<tt>java.library.path</tt>" property. </p>
+ * "<tt>java.library.path</tt>" property.
*
* @param libname
* The library name
@@ -1224,7 +1237,7 @@
* in the future will have assertions enabled or disabled by default.
* This setting may be overridden on a per-package or per-class basis by
* invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
- * #setClassAssertionStatus(String, boolean)}. </p>
+ * #setClassAssertionStatus(String, boolean)}.
*
* @param enabled
* <tt>true</tt> if classes loaded by this class loader will
@@ -1308,7 +1321,6 @@
* status settings associated with the class loader. This method is
* provided so that class loaders can be made to ignore any command line or
* persistent assertion status settings and "start with a clean slate."
- * </p>
*
* @since 1.4
*/
diff --git a/ojluni/src/main/java/java/lang/Override.java b/ojluni/src/main/java/java/lang/Override.java
index f708105..bf77344 100644
--- a/ojluni/src/main/java/java/lang/Override.java
+++ b/ojluni/src/main/java/java/lang/Override.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
*
* @author Peter von der Ahé
* @author Joshua Bloch
- * @jls 9.6.1.4 Override
+ * @jls 9.6.1.4 @Override
* @since 1.5
*/
@Target(ElementType.METHOD)
diff --git a/ojluni/src/main/java/java/lang/System.java b/ojluni/src/main/java/java/lang/System.java
index 4797c1b..6e8f74f 100644
--- a/ojluni/src/main/java/java/lang/System.java
+++ b/ojluni/src/main/java/java/lang/System.java
@@ -41,6 +41,8 @@
import java.util.PropertyPermission;
import libcore.icu.ICU;
import libcore.io.Libcore;
+import libcore.util.TimeZoneDataFiles;
+
import sun.reflect.CallerSensitive;
import sun.security.util.SecurityConstants;
/**
@@ -996,7 +998,7 @@
// is prioritized over the properties in ICUConfig.properties. The issue with using
// that is that it doesn't play well with jarjar and it needs complicated build rules
// to change its default value.
- String icuDataPath = generateIcuDataPath();
+ String icuDataPath = TimeZoneDataFiles.generateIcuDataPath();
p.put("android.icu.impl.ICUBinary.dataPath", icuDataPath);
parsePropertyAssignments(p, specialProperties());
@@ -1023,37 +1025,6 @@
return p;
}
- private static String generateIcuDataPath() {
- StringBuilder icuDataPathBuilder = new StringBuilder();
- // ICU should first look in ANDROID_DATA. This is used for (optional) timezone data.
- String dataIcuDataPath = getEnvironmentPath("ANDROID_DATA", "/misc/zoneinfo/current/icu");
- if (dataIcuDataPath != null) {
- icuDataPathBuilder.append(dataIcuDataPath);
- }
-
- // ICU should always look in ANDROID_ROOT.
- String systemIcuDataPath = getEnvironmentPath("ANDROID_ROOT", "/usr/icu");
- if (systemIcuDataPath != null) {
- if (icuDataPathBuilder.length() > 0) {
- icuDataPathBuilder.append(":");
- }
- icuDataPathBuilder.append(systemIcuDataPath);
- }
- return icuDataPathBuilder.toString();
- }
-
- /**
- * Creates a path by combining the value of an environment variable with a relative path.
- * Returns {@code null} if the environment variable is not set.
- */
- private static String getEnvironmentPath(String environmentVariable, String path) {
- String variable = getenv(environmentVariable);
- if (variable == null) {
- return null;
- }
- return variable + path;
- }
-
private static Properties initProperties() {
Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableProps);
setDefaultChangeableProperties(p);
diff --git a/ojluni/src/main/java/java/lang/annotation/ElementType.java b/ojluni/src/main/java/java/lang/annotation/ElementType.java
index 13b48f6..4590f39 100644
--- a/ojluni/src/main/java/java/lang/annotation/ElementType.java
+++ b/ojluni/src/main/java/java/lang/annotation/ElementType.java
@@ -26,15 +26,49 @@
package java.lang.annotation;
/**
- * A program element type. The constants of this enumerated type
- * provide a simple classification of the declared elements in a
- * Java program.
+ * The constants of this enumerated type provide a simple classification of the
+ * syntactic locations where annotations may appear in a Java program. These
+ * constants are used in {@link Target java.lang.annotation.Target}
+ * meta-annotations to specify where it is legal to write annotations of a
+ * given type.
*
- * <p>These constants are used with the {@link Target} meta-annotation type
- * to specify where it is legal to use an annotation type.
+ * <p>The syntactic locations where annotations may appear are split into
+ * <em>declaration contexts</em> , where annotations apply to declarations, and
+ * <em>type contexts</em> , where annotations apply to types used in
+ * declarations and expressions.
+ *
+ * <p>The constants {@link #ANNOTATION_TYPE} , {@link #CONSTRUCTOR} , {@link
+ * #FIELD} , {@link #LOCAL_VARIABLE} , {@link #METHOD} , {@link #PACKAGE} ,
+ * {@link #PARAMETER} , {@link #TYPE} , and {@link #TYPE_PARAMETER} correspond
+ * to the declaration contexts in JLS 9.6.4.1.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
+ * field declaration.
+ *
+ * <p>The constant {@link #TYPE_USE} corresponds to the 15 type contexts in JLS
+ * 4.11, as well as to two declaration contexts: type declarations (including
+ * annotation type declarations) and type parameter declarations.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)} may be written on the type of a field
+ * (or within the type of the field, if it is a nested, parameterized, or array
+ * type), and may also appear as a modifier for, say, a class declaration.
+ *
+ * <p>The {@code TYPE_USE} constant includes type declarations and type
+ * parameter declarations as a convenience for designers of type checkers which
+ * give semantics to annotation types. For example, if the annotation type
+ * {@code NonNull} is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)}, then {@code @NonNull}
+ * {@code class C {...}} could be treated by a type checker as indicating that
+ * all variables of class {@code C} are non-null, while still allowing
+ * variables of other classes to be non-null or not non-null based on whether
+ * {@code @NonNull} appears at the variable's declaration.
*
* @author Joshua Bloch
* @since 1.5
+ * @jls 9.6.4.1 @Target
+ * @jls 4.1 The Kinds of Types and Values
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
diff --git a/ojluni/src/main/java/java/lang/invoke/CallSite.java b/ojluni/src/main/java/java/lang/invoke/CallSite.java
index f9338e6..b2226bf 100644
--- a/ojluni/src/main/java/java/lang/invoke/CallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/CallSite.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@
* <p>
* Here is a sample use of call sites and bootstrap methods which links every
* dynamic call site to print its arguments:
-<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
+<blockquote><pre>{@code
static void test() throws Throwable {
// THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
@@ -80,7 +80,7 @@
// ignore caller and name, but match the type:
return new ConstantCallSite(printArgs.asType(type));
}
-</pre></blockquote>
+}</pre></blockquote>
* @author John Rose, JSR 292 EG
*/
abstract
@@ -102,13 +102,12 @@
* via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
* @throws NullPointerException if the proposed type is null
*/
-
/*package-private*/
CallSite(MethodType type) {
// Android-changed: No cache for these so create uninitializedCallSite target here using
// method handle transformations to create a method handle that has the expected method
// type but throws an IllegalStateException.
- // target = type.invokers().uninitializedCallSite();
+ // target = makeUninitializedCallSite(type);
this.target = MethodHandles.throwException(type.returnType(), IllegalStateException.class);
this.target = MethodHandles.insertArguments(
this.target, 0, new IllegalStateException("uninitialized call site"));
@@ -144,7 +143,7 @@
* or if the target returned by the hook is not of the given {@code targetType}
* @throws NullPointerException if the hook returns a null value
* @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
- * @throws Throwable anything else thrown by the the hook function
+ * @throws Throwable anything else thrown by the hook function
*/
/*package-private*/
CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
@@ -223,19 +222,19 @@
* which has been linked to this call site.
* <p>
* This method is equivalent to the following code:
- * <blockquote><pre>
+ * <blockquote><pre>{@code
* MethodHandle getTarget, invoker, result;
* getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
* invoker = MethodHandles.exactInvoker(this.type());
* result = MethodHandles.foldArguments(invoker, getTarget)
- * </pre></blockquote>
+ * }</pre></blockquote>
*
* @return a method handle which always invokes this call site's current target
*/
public abstract MethodHandle dynamicInvoker();
/*non-public*/ MethodHandle makeDynamicInvoker() {
- // Android-changed: Use bindTo() rather than bindReceiver() (not implemented).
+ // Android-changed: Use bindTo() rather than bindArgumentL() (not implemented).
MethodHandle getTarget = GET_TARGET.bindTo(this);
MethodHandle invoker = MethodHandles.exactInvoker(this.type());
return MethodHandles.foldArguments(invoker, getTarget);
@@ -302,7 +301,7 @@
// Object info,
// // Caller information:
// Class<?> callerClass) {
- // Object caller = IMPL_LOOKUP.in(callerClass);
+ // MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass);
// CallSite site;
// try {
// Object binding;
@@ -314,14 +313,44 @@
// } else {
// Object[] argv = (Object[]) info;
// maybeReBoxElements(argv);
- // if (3 + argv.length > 255)
- // throw new BootstrapMethodError("too many bootstrap method arguments");
- // MethodType bsmType = bootstrapMethod.type();
- // if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
- // binding = bootstrapMethod.invoke(caller, name, type, argv);
- // else
- // binding = MethodHandles.spreadInvoker(bsmType, 3)
- // .invoke(bootstrapMethod, caller, name, type, argv);
+ // switch (argv.length) {
+ // case 0:
+ // binding = bootstrapMethod.invoke(caller, name, type);
+ // break;
+ // case 1:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0]);
+ // break;
+ // case 2:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1]);
+ // break;
+ // case 3:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2]);
+ // break;
+ // case 4:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2], argv[3]);
+ // break;
+ // case 5:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2], argv[3], argv[4]);
+ // break;
+ // case 6:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+ // break;
+ // default:
+ // final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
+ // if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
+ // throw new BootstrapMethodError("too many bootstrap method arguments");
+ // MethodType bsmType = bootstrapMethod.type();
+ // MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
+ // MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
+ // MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+ // binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv);
+ // }
// }
// //System.out.println("BSM for "+name+type+" => "+binding);
// if (binding instanceof CallSite) {
@@ -330,7 +359,7 @@
// throw new ClassCastException("bootstrap method failed to produce a CallSite");
// }
// if (!site.getTarget().type().equals(type))
- // throw new WrongMethodTypeException("wrong type: "+site.getTarget());
+ // throw wrongTargetType(site.getTarget(), type);
// } catch (Throwable ex) {
// BootstrapMethodError bex;
// if (ex instanceof BootstrapMethodError)
@@ -341,6 +370,7 @@
// }
// return site;
// }
+
// private static Object maybeReBox(Object x) {
// if (x instanceof Integer) {
// int xi = (int) x;
diff --git a/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java b/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java
index 2d9fede..f27d0e7b 100644
--- a/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,7 +75,7 @@
* or if the target returned by the hook is not of the given {@code targetType}
* @throws NullPointerException if the hook returns a null value
* @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
- * @throws Throwable anything else thrown by the the hook function
+ * @throws Throwable anything else thrown by the hook function
*/
protected ConstantCallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
super(targetType, createTargetHook);
@@ -85,7 +85,7 @@
/**
* Returns the target method of the call site, which behaves
* like a {@code final} field of the {@code ConstantCallSite}.
- * That is, the the target is always the original value passed
+ * That is, the target is always the original value passed
* to the constructor call which created this instance.
*
* @return the immutable linkage state of this call site, a constant method handle
diff --git a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
index 37ca324..bb01d4c 100644
--- a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
* Here is an example of a mutable call site which introduces a
* state variable into a method handle chain.
* <!-- JavaDocExamplesTest.testMutableCallSite -->
- * <blockquote><pre>
+ * <blockquote><pre>{@code
MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
MethodHandle MH_name = name.dynamicInvoker();
MethodType MT_str1 = MethodType.methodType(String.class);
@@ -52,10 +52,10 @@
name.setTarget(MethodHandles.constant(String.class, "Fred"));
assertEquals("FRED", (String) worker1.invokeExact());
// (mutation can be continued indefinitely)
- * </pre></blockquote>
+ * }</pre></blockquote>
* <p>
* The same call site may be used in several places at once.
- * <blockquote><pre>
+ * <blockquote><pre>{@code
MethodType MT_str2 = MethodType.methodType(String.class, String.class);
MethodHandle MH_cat = lookup().findVirtual(String.class,
"concat", methodType(String.class, String.class));
@@ -65,7 +65,7 @@
name.setTarget(MethodHandles.constant(String.class, "Wilma"));
assertEquals("WILMA", (String) worker1.invokeExact());
assertEquals("Wilma, dear?", (String) worker2.invokeExact());
- * </pre></blockquote>
+ * }</pre></blockquote>
* <p>
* <em>Non-synchronization of target values:</em>
* A write to a mutable call site's target does not force other threads
diff --git a/ojluni/src/main/java/java/lang/reflect/Array.java b/ojluni/src/main/java/java/lang/reflect/Array.java
index 8285be7..790a930 100644
--- a/ojluni/src/main/java/java/lang/reflect/Array.java
+++ b/ojluni/src/main/java/java/lang/reflect/Array.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,8 @@
* Array.newInstance(componentType, x);
* </pre>
* </blockquote>
+ * <p>The number of dimensions of the new array must not
+ * exceed 255.
*
* @param componentType the {@code Class} object representing the
* component type of the new array
@@ -64,7 +66,9 @@
* @return the new array
* @exception NullPointerException if the specified
* {@code componentType} parameter is null
- * @exception IllegalArgumentException if componentType is {@link Void#TYPE}
+ * @exception IllegalArgumentException if componentType is {@link
+ * Void#TYPE} or if the number of dimensions of the requested array
+ * instance exceed 255.
* @exception NegativeArraySizeException if the specified {@code length}
* is negative
*/
@@ -88,8 +92,7 @@
* {@code componentType}.
*
* <p>The number of dimensions of the new array must not
- * exceed the number of array dimensions supported by the
- * implementation (typically 255).
+ * exceed 255.
*
* @param componentType the {@code Class} object representing the component
* type of the new array
@@ -99,10 +102,9 @@
* @exception NullPointerException if the specified
* {@code componentType} argument is null
* @exception IllegalArgumentException if the specified {@code dimensions}
- * argument is a zero-dimensional array, or if the number of
- * requested dimensions exceeds the limit on the number of array dimensions
- * supported by the implementation (typically 255), or if componentType
- * is {@link Void#TYPE}.
+ * argument is a zero-dimensional array, if componentType is {@link
+ * Void#TYPE}, or if the number of dimensions of the requested array
+ * instance exceed 255.
* @exception NegativeArraySizeException if any of the components in
* the specified {@code dimensions} argument is negative.
*/
diff --git a/ojluni/src/main/java/java/lang/reflect/Constructor.java b/ojluni/src/main/java/java/lang/reflect/Constructor.java
index dbbb6b2..de7176b 100644
--- a/ojluni/src/main/java/java/lang/reflect/Constructor.java
+++ b/ojluni/src/main/java/java/lang/reflect/Constructor.java
@@ -27,6 +27,8 @@
package java.lang.reflect;
import dalvik.annotation.optimization.FastNative;
+import libcore.util.EmptyArray;
+
import java.lang.annotation.Annotation;
import java.util.Comparator;
@@ -127,11 +129,17 @@
@Override
public Class<?>[] getParameterTypes() {
// Android-changed: This is handled by Executable.
- return super.getParameterTypesInternal();
+ Class<?>[] paramTypes = super.getParameterTypesInternal();
+ if (paramTypes == null) {
+ return EmptyArray.CLASS;
+ }
+
+ return paramTypes;
}
/**
* {@inheritDoc}
+ * @since 1.8
*/
public int getParameterCount() {
// Android-changed: This is handled by Executable.
diff --git a/ojluni/src/main/java/java/lang/reflect/Executable.java b/ojluni/src/main/java/java/lang/reflect/Executable.java
index 59f50e1..7945ad6 100644
--- a/ojluni/src/main/java/java/lang/reflect/Executable.java
+++ b/ojluni/src/main/java/java/lang/reflect/Executable.java
@@ -26,7 +26,6 @@
package java.lang.reflect;
import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
import java.lang.annotation.Annotation;
import java.util.Objects;
@@ -621,30 +620,16 @@
/**
* Returns an array of {@code Class} objects associated with the parameter types of this
- * Executable. If the Executable was declared with no parameters, an empty array will be
+ * Executable. If the Executable was declared with no parameters, {@code null} will be
* returned.
*
- * @return the parameter types
+ * @return the parameter types, or {@code null} if no parameters were declared.
*/
- final Class<?>[] getParameterTypesInternal() {
- Dex dex = declaringClassOfOverriddenMethod.getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- if (types.length == 0) {
- return EmptyArray.CLASS;
- }
- Class<?>[] parametersArray = new Class[types.length];
- for (int i = 0; i < types.length; i++) {
- // Note, in the case of a Proxy the dex cache types are equal.
- parametersArray[i] = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
- }
- return parametersArray;
- }
+ @FastNative
+ final native Class<?>[] getParameterTypesInternal();
- final int getParameterCountInternal() {
- Dex dex = declaringClassOfOverriddenMethod.getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- return types.length;
- }
+ @FastNative
+ final native int getParameterCountInternal();
// Android provides a more efficient implementation of this method for Executable than the one
// implemented in AnnotatedElement.
@@ -731,52 +716,17 @@
private native String[] getSignatureAnnotation();
final boolean equalNameAndParametersInternal(Method m) {
- return getName().equals(m.getName()) && equalMethodParameters(m.getParameterTypes());
+ return getName().equals(m.getName()) && (compareMethodParametersInternal(m) == 0);
}
- private boolean equalMethodParameters(Class<?>[] params) {
- Dex dex = declaringClassOfOverriddenMethod.getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- if (types.length != params.length) {
- return false;
- }
- for (int i = 0; i < types.length; i++) {
- if (declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]) != params[i]) {
- return false;
- }
- }
- return true;
- }
+ @FastNative
+ native int compareMethodParametersInternal(Method meth);
- final int compareMethodParametersInternal(Class<?>[] params) {
- Dex dex = declaringClassOfOverriddenMethod.getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- int length = Math.min(types.length, params.length);
- for (int i = 0; i < length; i++) {
- Class<?> aType = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
- Class<?> bType = params[i];
- if (aType != bType) {
- int comparison = aType.getName().compareTo(bType.getName());
- if (comparison != 0) {
- return comparison;
- }
- }
- }
- return types.length - params.length;
- }
+ @FastNative
+ final native String getMethodNameInternal();
- final String getMethodNameInternal() {
- Dex dex = declaringClassOfOverriddenMethod.getDex();
- int nameIndex = dex.nameIndexFromMethodIndex(dexMethodIndex);
- return declaringClassOfOverriddenMethod.getDexCacheString(dex, nameIndex);
- }
-
- final Class<?> getMethodReturnTypeInternal() {
- Dex dex = declaringClassOfOverriddenMethod.getDex();
- int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
- // Note, in the case of a Proxy the dex cache types are equal.
- return declaringClassOfOverriddenMethod.getDexCacheType(dex, returnTypeIndex);
- }
+ @FastNative
+ final native Class<?> getMethodReturnTypeInternal();
/** A cheap implementation for {@link Method#isDefault()}. */
final boolean isDefaultMethodInternal() {
diff --git a/ojluni/src/main/java/java/lang/reflect/Field.java b/ojluni/src/main/java/java/lang/reflect/Field.java
index 2f1bc31..a691766 100644
--- a/ojluni/src/main/java/java/lang/reflect/Field.java
+++ b/ojluni/src/main/java/java/lang/reflect/Field.java
@@ -27,7 +27,6 @@
package java.lang.reflect;
import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
import java.lang.annotation.Annotation;
import java.util.Objects;
@@ -85,11 +84,13 @@
}
return "throws";
}
- Dex dex = declaringClass.getDex();
- int nameIndex = dex.nameIndexFromFieldIndex(dexFieldIndex);
- return declaringClass.getDexCacheString(dex, nameIndex);
+
+ return getNameInternal();
}
+ @FastNative
+ private native String getNameInternal();
+
/**
* Returns the Java language modifiers for the field represented
* by this {@code Field} object, as an integer. The {@code Modifier} class should
diff --git a/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java b/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
index 1650803..3fd70d3 100644
--- a/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
+++ b/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,4 +35,22 @@
*/
public class GenericSignatureFormatError extends ClassFormatError {
private static final long serialVersionUID = 6709919147137911034L;
+
+ /**
+ * Constructs a new {@code GenericSignatureFormatError}.
+ *
+ */
+ public GenericSignatureFormatError() {
+ super();
+ }
+
+ /**
+ * Constructs a new {@code GenericSignatureFormatError} with the
+ * specified message.
+ *
+ * @param message the detail message, may be {@code null}
+ */
+ public GenericSignatureFormatError(String message) {
+ super(message);
+ }
}
diff --git a/ojluni/src/main/java/java/lang/reflect/Member.java b/ojluni/src/main/java/java/lang/reflect/Member.java
index 7d51c18..2241d45 100644
--- a/ojluni/src/main/java/java/lang/reflect/Member.java
+++ b/ojluni/src/main/java/java/lang/reflect/Member.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,14 +42,12 @@
/**
* Identifies the set of all public members of a class or interface,
* including inherited members.
- * @see java.lang.SecurityManager#checkMemberAccess
*/
public static final int PUBLIC = 0;
/**
* Identifies the set of declared members of a class or interface.
* Inherited members are not included.
- * @see java.lang.SecurityManager#checkMemberAccess
*/
public static final int DECLARED = 1;
@@ -87,6 +85,7 @@
*
* @return true if and only if this member was introduced by
* the compiler.
+ * @jls 13.1 The Form of a Binary
* @since 1.5
*/
public boolean isSynthetic();
diff --git a/ojluni/src/main/java/java/lang/reflect/Method.java b/ojluni/src/main/java/java/lang/reflect/Method.java
index 3636a1b..ddda93d 100644
--- a/ojluni/src/main/java/java/lang/reflect/Method.java
+++ b/ojluni/src/main/java/java/lang/reflect/Method.java
@@ -30,6 +30,7 @@
import java.lang.annotation.Annotation;
import java.util.Comparator;
import libcore.reflect.Types;
+import libcore.util.EmptyArray;
/**
* A {@code Method} provides information about, and access to, a single method
@@ -64,7 +65,7 @@
}
int comparison = a.getName().compareTo(b.getName());
if (comparison == 0) {
- comparison = a.compareMethodParametersInternal(b.getParameterTypes());
+ comparison = a.compareMethodParametersInternal(b);
if (comparison == 0) {
// This is necessary for methods that have covariant return types.
Class<?> aReturnType = a.getReturnType();
@@ -137,7 +138,6 @@
* @return the return type for the method this object represents
*/
public Class<?> getReturnType() {
- // Android-changed: This is handled by Executable.
return getMethodReturnTypeInternal();
}
@@ -176,11 +176,17 @@
@Override
public Class<?>[] getParameterTypes() {
// Android-changed: This is handled by Executable.
- return super.getParameterTypesInternal();
+ Class<?>[] paramTypes = super.getParameterTypesInternal();
+ if (paramTypes == null) {
+ return EmptyArray.CLASS;
+ }
+
+ return paramTypes;
}
/**
* {@inheritDoc}
+ * @since 1.8
*/
public int getParameterCount() {
// Android-changed: This is handled by Executable.
diff --git a/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java b/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java
index b8e8e63..96a2d21 100644
--- a/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java
+++ b/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
index 4c5d3de..20372a4 100644
--- a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
+++ b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,8 @@
*
* @since 1.5
*/
+// Android-changed: Removed AnnotatedElement super-class due to excluded support
+// for runtime type annotations
public interface TypeVariable<D extends GenericDeclaration> extends Type {
/**
* Returns an array of {@code Type} objects representing the
@@ -86,4 +88,18 @@
* @return the name of this type variable, as it appears in the source code
*/
String getName();
+
+ /**
+ * Returns an array of AnnotatedType objects that represent the use of
+ * types to denote the upper bounds of the type parameter represented by
+ * this TypeVariable. The order of the objects in the array corresponds to
+ * the order of the bounds in the declaration of the type parameter.
+ *
+ * Returns an array of length 0 if the type parameter declares no bounds.
+ *
+ * @return an array of objects representing the upper bounds of the type variable
+ * @since 1.8
+ */
+ // Android-changed: Excluded support for runtime type annotations
+ // AnnotatedType[] getAnnotatedBounds();
}
diff --git a/ojluni/src/main/java/java/net/DatagramSocket.java b/ojluni/src/main/java/java/net/DatagramSocket.java
index cdb8ef7..34f3a2d 100755
--- a/ojluni/src/main/java/java/net/DatagramSocket.java
+++ b/ojluni/src/main/java/java/net/DatagramSocket.java
@@ -1347,12 +1347,17 @@
factory = fac;
}
- /** @hide */
+ /**
+ * Android-added: for testing and internal use.
+ *
+ * @hide internal use only
+ */
public FileDescriptor getFileDescriptor$() {
return impl.fd;
}
/**
+ * Android-added:
* Sets the network interface used by this socket. Any packets sent
* via this socket are transmitted via the specified interface. Any
* packets received by this socket will come from the specified
diff --git a/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java b/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java
index 18465ba..ad62c58 100644
--- a/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java
+++ b/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007,2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
*/
class DefaultDatagramSocketImplFactory {
- static Class prefixImplClass = null;
+ static Class<?> prefixImplClass = null;
static {
String prefix = null;
@@ -53,10 +53,10 @@
}
/**
- * Creates a new {@code DatagramSocketImpl} instance.
+ * Creates a new <code>DatagramSocketImpl</code> instance.
*
* @param isMulticast true if this impl if for a MutlicastSocket
- * @return a new instance of a {@code DatagramSocketImpl}.
+ * @return a new instance of a <code>DatagramSocketImpl</code>.
*/
static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast /*unused on unix*/)
throws SocketException {
diff --git a/ojluni/src/main/java/java/net/DefaultInterface.java b/ojluni/src/main/java/java/net/DefaultInterface.java
index 9f4dfe1..0c31cb6 100644
--- a/ojluni/src/main/java/java/net/DefaultInterface.java
+++ b/ojluni/src/main/java/java/net/DefaultInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
package java.net;
/**
- * Choose a network inteface to be the default for
+ * Choose a network interface to be the default for
* outgoing IPv6 traffic that does not specify a scope_id (and which needs one).
*
* Platforms that do not require a default interface may return null
diff --git a/ojluni/src/main/java/java/net/PlainSocketImpl.java b/ojluni/src/main/java/java/net/PlainSocketImpl.java
index 7177098..f02006d 100644
--- a/ojluni/src/main/java/java/net/PlainSocketImpl.java
+++ b/ojluni/src/main/java/java/net/PlainSocketImpl.java
@@ -25,15 +25,34 @@
*/
package java.net;
+import android.system.ErrnoException;
+
import java.io.IOException;
import java.io.FileDescriptor;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
+import libcore.io.AsynchronousCloseMonitor;
+import libcore.io.IoBridge;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+
import jdk.net.*;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.EAGAIN;
+import static android.system.OsConstants.EBADF;
+import static android.system.OsConstants.EINVAL;
+import static android.system.OsConstants.MSG_OOB;
+import static android.system.OsConstants.POLLERR;
+import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.SHUT_RDWR;
import static sun.net.ExtendedOptionsImpl.*;
+// Android-changed: Rewritten to use android.system POSIX calls and assume AF_INET6.
/*
* On Unix systems we simply delegate to native methods.
*
@@ -91,29 +110,180 @@
}
}
- native void socketCreate(boolean isServer) throws IOException;
+ void socketCreate(boolean isStream) throws IOException {
+ // The fd object must not change after calling bind, because we rely on this undocumented
+ // behaviour. See libcore.java.net.SocketTest#testFileDescriptorStaysSame.
+ fd.setInt$(IoBridge.socket(AF_INET6, isStream ? SOCK_STREAM : SOCK_DGRAM, 0).getInt$());
- native void socketConnect(InetAddress address, int port, int timeout)
- throws IOException;
+ if (serverSocket != null) {
+ IoUtils.setBlocking(fd, false);
+ IoBridge.setSocketOption(fd, SO_REUSEADDR, true);
+ }
+ }
- native void socketBind(InetAddress address, int port)
- throws IOException;
+ void socketConnect(InetAddress address, int port, int timeout) throws IOException {
+ if (fd == null || !fd.valid()) {
+ throw new SocketException("Socket closed");
+ }
- native void socketListen(int count) throws IOException;
+ IoBridge.connect(fd, address, port, timeout);
- native void socketAccept(SocketImpl s) throws IOException;
+ this.address = address;
+ this.port = port;
- native int socketAvailable() throws IOException;
+ if (localport == 0) {
+ // If socket is pending close, fd becomes an AF_UNIX socket and calling
+ // getLocalInetSocketAddress will fail.
+ // http://b/34645743
+ if (!isClosedOrPending()) {
+ localport = IoBridge.getLocalInetSocketAddress(fd).getPort();
+ }
+ }
+ }
- native void socketClose0(boolean useDeferredClose) throws IOException;
+ void socketBind(InetAddress address, int port) throws IOException {
+ if (fd == null || !fd.valid()) {
+ throw new SocketException("Socket closed");
+ }
- native void socketShutdown(int howto) throws IOException;
+ IoBridge.bind(fd, address, port);
+
+ this.address = address;
+ if (port == 0) {
+ // Now that we're a connected socket, let's extract the port number that the system
+ // chose for us and store it in the Socket object.
+ localport = IoBridge.getLocalInetSocketAddress(fd).getPort();
+ } else {
+ localport = port;
+ }
+ }
+
+ void socketListen(int count) throws IOException {
+ if (fd == null || !fd.valid()) {
+ throw new SocketException("Socket closed");
+ }
+
+ try {
+ Libcore.os.listen(fd, count);
+ } catch (ErrnoException errnoException) {
+ throw errnoException.rethrowAsSocketException();
+ }
+ }
+
+ void socketAccept(SocketImpl s) throws IOException {
+ if (fd == null || !fd.valid()) {
+ throw new SocketException("Socket closed");
+ }
+
+ // poll() with a timeout of 0 means "poll for zero millis", but a Socket timeout == 0 means
+ // "wait forever". When timeout == 0 we pass -1 to poll.
+ if (timeout <= 0) {
+ IoBridge.poll(fd, POLLIN | POLLERR, -1);
+ } else {
+ IoBridge.poll(fd, POLLIN | POLLERR, timeout);
+ }
+
+ InetSocketAddress peerAddress = new InetSocketAddress();
+ try {
+ FileDescriptor newfd = Libcore.os.accept(fd, peerAddress);
+
+ s.fd.setInt$(newfd.getInt$());
+ s.address = peerAddress.getAddress();
+ s.port = peerAddress.getPort();
+ } catch (ErrnoException errnoException) {
+ if (errnoException.errno == EAGAIN) {
+ throw new SocketTimeoutException(errnoException);
+ } else if (errnoException.errno == EINVAL || errnoException.errno == EBADF) {
+ throw new SocketException("Socket closed");
+ }
+ errnoException.rethrowAsSocketException();
+ }
+
+ s.localport = IoBridge.getLocalInetSocketAddress(s.fd).getPort();
+ }
+
+ int socketAvailable() throws IOException {
+ return IoBridge.available(fd);
+ }
+
+ void socketClose0(boolean useDeferredClose) throws IOException {
+ if (fd == null || !fd.valid()) {
+ throw new SocketException("socket already closed");
+ }
+
+ FileDescriptor markerFD = null;
+ if (useDeferredClose) {
+ markerFD = getMarkerFD();
+ }
+
+ if (useDeferredClose && markerFD != null) {
+ try {
+ Libcore.os.dup2(markerFD, fd.getInt$());
+ Libcore.os.close(markerFD);
+
+ // This effectively closes the socket, needs to signal threads that blocks on this
+ // file descriptor.
+ AsynchronousCloseMonitor.signalBlockedThreads(fd);
+ } catch (ErrnoException errnoException) {
+ // close should not throw
+ }
+ } else {
+ // If requested or a markerFD cannot be created, a non-deferred close is performed
+ // instead.
+ IoBridge.closeAndSignalBlockedThreads(fd);
+ }
+ }
+
+ /*
+ * Create the marker file descriptor by establishing a loopback connection which we shutdown but
+ * do not close the fd. The result is an fd that can be used for read/write.
+ *
+ * The purpose is to keep hold of the raw fd handle until we are sure it is not used in any
+ * thread. Otherwise if we close the file descriptor directly, the system might reuse the raw fd
+ * number and threads holding old fd value might behave incorrectly.
+ */
+ private FileDescriptor getMarkerFD() throws SocketException {
+ FileDescriptor fd1 = new FileDescriptor();
+ FileDescriptor fd2 = new FileDescriptor();
+ try {
+ Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd1, fd2);
+
+ // Shutdown fd1, any reads to this fd will get EOF; any writes will get an error.
+ Libcore.os.shutdown(fd1, SHUT_RDWR);
+ Libcore.os.close(fd2);
+ } catch (ErrnoException errnoException) {
+ // We might have reached the maximum file descriptor number and socketpair(2) would
+ // fail. In this case, return null and let caller to fall back to an alternative method
+ // that does not allocate more file descriptors.
+ return null;
+ }
+ return fd1;
+ }
+
+ void socketShutdown(int howto) throws IOException {
+ try {
+ Libcore.os.shutdown(fd, howto);
+ } catch (ErrnoException errnoException) {
+ throw errnoException.rethrowAsIOException();
+ }
+ }
native void socketSetOption0(int cmd, boolean on, Object value)
throws SocketException;
native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
- native void socketSendUrgentData(int data) throws IOException;
+ void socketSendUrgentData(int data) throws IOException {
+ if (fd == null || !fd.valid()) {
+ throw new SocketException("Socket closed");
+ }
+
+ try {
+ byte[] buffer = new byte[] { (byte) data };
+ Libcore.os.sendto(fd, buffer, 0, 1, MSG_OOB, null, 0);
+ } catch (ErrnoException errnoException) {
+ throw errnoException.rethrowAsSocketException();
+ }
+ }
}
diff --git a/ojluni/src/main/java/java/net/ServerSocket.java b/ojluni/src/main/java/java/net/ServerSocket.java
index ccf88f8..670acf2 100644
--- a/ojluni/src/main/java/java/net/ServerSocket.java
+++ b/ojluni/src/main/java/java/net/ServerSocket.java
@@ -922,4 +922,12 @@
/* Not implemented yet */
}
+ /**
+ * Android-added: for testing and internal use.
+ *
+ * @hide internal use only
+ */
+ public FileDescriptor getFileDescriptor$() {
+ return impl.getFileDescriptor();
+ }
}
diff --git a/ojluni/src/main/java/java/net/Socket.java b/ojluni/src/main/java/java/net/Socket.java
index ed18b48..9d566b1 100644
--- a/ojluni/src/main/java/java/net/Socket.java
+++ b/ojluni/src/main/java/java/net/Socket.java
@@ -1769,6 +1769,8 @@
}
/**
+ * Android-added: for testing and internal use.
+ *
* @hide internal use only
*/
public FileDescriptor getFileDescriptor$() {
diff --git a/ojluni/src/main/java/java/net/SocketInputStream.java b/ojluni/src/main/java/java/net/SocketInputStream.java
index 2757412..f5c4c8f 100644
--- a/ojluni/src/main/java/java/net/SocketInputStream.java
+++ b/ojluni/src/main/java/java/net/SocketInputStream.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -153,11 +153,12 @@
}
// bounds check
- if (length <= 0 || off < 0 || off + length > b.length) {
+ if (length <= 0 || off < 0 || length > b.length - off) {
if (length == 0) {
return 0;
}
- throw new ArrayIndexOutOfBoundsException();
+ throw new ArrayIndexOutOfBoundsException("length == " + length
+ + " off == " + off + " buffer length == " + b.length);
}
boolean gotReset = false;
diff --git a/ojluni/src/main/java/java/net/SocketOutputStream.java b/ojluni/src/main/java/java/net/SocketOutputStream.java
index d37a7d7..c0173f0 100644
--- a/ojluni/src/main/java/java/net/SocketOutputStream.java
+++ b/ojluni/src/main/java/java/net/SocketOutputStream.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -95,12 +95,12 @@
* @exception IOException If an I/O error has occurred.
*/
private void socketWrite(byte b[], int off, int len) throws IOException {
-
- if (len <= 0 || off < 0 || off + len > b.length) {
+ if (len <= 0 || off < 0 || len > b.length - off) {
if (len == 0) {
return;
}
- throw new ArrayIndexOutOfBoundsException();
+ throw new ArrayIndexOutOfBoundsException("len == " + len
+ + " off == " + off + " buffer length == " + b.length);
}
FileDescriptor fd = impl.acquireFD();
diff --git a/ojluni/src/main/java/java/security/AccessControlContext.java b/ojluni/src/main/java/java/security/AccessControlContext.java
index 86a88f0..e95cff2 100644
--- a/ojluni/src/main/java/java/security/AccessControlContext.java
+++ b/ojluni/src/main/java/java/security/AccessControlContext.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/AccessController.java b/ojluni/src/main/java/java/security/AccessController.java
index 1f7bdc5..b4d544c 100644
--- a/ojluni/src/main/java/java/security/AccessController.java
+++ b/ojluni/src/main/java/java/security/AccessController.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java b/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
index 5224158..7355405 100644
--- a/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
+++ b/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
@@ -68,34 +68,34 @@
*
* <p> Android provides the following <code>AlgorithmParameterGenerator</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>AES</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DES</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DESede</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DH</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DSA</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr class="deprecated">
+ * <td>AES</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DES</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DESede</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>DH</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DSA</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/AlgorithmParameters.java b/ojluni/src/main/java/java/security/AlgorithmParameters.java
index af5ed7e..36bb3ee 100644
--- a/ojluni/src/main/java/java/security/AlgorithmParameters.java
+++ b/ojluni/src/main/java/java/security/AlgorithmParameters.java
@@ -48,58 +48,102 @@
*
* <p> Android provides the following <code>AlgorithmParameters</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>AES</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>Blowfish</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>DES</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DH</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>GCM</td>
- * <td>22+</td>
- * </tr>
- * <tr>
- * <td>IES</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>OAEP</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PKCS12PBE</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PSS</td>
- * <td>1–8, 24+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>AES</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>BLOWFISH</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>DES</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DESede</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DH</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>EC</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>GCM</td>
+ * <td>22+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>IES</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>OAEP</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA1AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA1AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA224AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA224AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA256AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA256AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA384AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA384AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA512AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA512AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PKCS12PBE</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PSS</td>
+ * <td>1-8,24+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/AuthProvider.java b/ojluni/src/main/java/java/security/AuthProvider.java
index 0308291..23ddb0a 100644
--- a/ojluni/src/main/java/java/security/AuthProvider.java
+++ b/ojluni/src/main/java/java/security/AuthProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/CodeSource.java b/ojluni/src/main/java/java/security/CodeSource.java
index d678011..7396d91 100644
--- a/ojluni/src/main/java/java/security/CodeSource.java
+++ b/ojluni/src/main/java/java/security/CodeSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/DomainCombiner.java b/ojluni/src/main/java/java/security/DomainCombiner.java
index 7dc0849..5426bf6 100644
--- a/ojluni/src/main/java/java/security/DomainCombiner.java
+++ b/ojluni/src/main/java/java/security/DomainCombiner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/KeyFactory.java b/ojluni/src/main/java/java/security/KeyFactory.java
index 92149ae..a6b912c 100644
--- a/ojluni/src/main/java/java/security/KeyFactory.java
+++ b/ojluni/src/main/java/java/security/KeyFactory.java
@@ -69,34 +69,34 @@
*
* <p> Android provides the following <code>KeyFactory</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>DH</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>EC</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>RSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>X.509</td>
- * <td>1–8</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>DH</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>EC</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>RSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>X.509</td>
+ * <td>1-8</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/KeyPairGenerator.java b/ojluni/src/main/java/java/security/KeyPairGenerator.java
index c9fa996..1e46cee 100644
--- a/ojluni/src/main/java/java/security/KeyPairGenerator.java
+++ b/ojluni/src/main/java/java/security/KeyPairGenerator.java
@@ -111,30 +111,30 @@
*
* <p> Android provides the following <code>KeyPairGenerator</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>DH</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>EC</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>RSA</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>DH</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>EC</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>RSA</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/KeyStore.java b/ojluni/src/main/java/java/security/KeyStore.java
index 43ecd6d..d091781 100644
--- a/ojluni/src/main/java/java/security/KeyStore.java
+++ b/ojluni/src/main/java/java/security/KeyStore.java
@@ -156,42 +156,42 @@
*
* <p> Android provides the following <code>KeyStore</code> types:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>AndroidCAStore</td>
- * <td>14+</td>
- * </tr>
- * <tr>
- * <td>AndroidKeyStore</td>
- * <td>18+</td>
- * </tr>
- * <tr>
- * <td>BCPKCS12</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>BKS</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>BouncyCastle</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PKCS12</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PKCS12-DEF</td>
- * <td>1–8</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>AndroidCAStore</td>
+ * <td>14+</td>
+ * </tr>
+ * <tr>
+ * <td>AndroidKeyStore</td>
+ * <td>18+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>BCPKCS12</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>BKS</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>BouncyCastle</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PKCS12</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>PKCS12-DEF</td>
+ * <td>1-8</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These types are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/MessageDigest.java b/ojluni/src/main/java/java/security/MessageDigest.java
index d173048..df6c456 100644
--- a/ojluni/src/main/java/java/security/MessageDigest.java
+++ b/ojluni/src/main/java/java/security/MessageDigest.java
@@ -87,38 +87,38 @@
*
* <p> Android provides the following <code>MessageDigest</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>MD5</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA-1</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA-224</td>
- * <td>1–8,22+</td>
- * </tr>
- * <tr>
- * <td>SHA-256</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA-384</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA-512</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>MD5</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA-1</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA-224</td>
+ * <td>1-8,22+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA-256</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA-384</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA-512</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java b/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java
index fb34981..951e44e 100644
--- a/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java
+++ b/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,13 +58,13 @@
}
/**
- * Creates a <code>NoSuchAlgorithmException</code> with the specified
+ * Creates a {@code NoSuchAlgorithmException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <tt>null</tt> value is permitted,
+ * {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
@@ -73,13 +73,13 @@
}
/**
- * Creates a <code>NoSuchAlgorithmException</code> with the specified cause
- * and a detail message of <tt>(cause==null ? null : cause.toString())</tt>
+ * Creates a {@code NoSuchAlgorithmException} with the specified cause
+ * and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
- * <tt>cause</tt>).
+ * {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <tt>null</tt> value is permitted,
+ * {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
diff --git a/ojluni/src/main/java/java/security/Permission.java b/ojluni/src/main/java/java/security/Permission.java
index 9f04ac4..8d170c0 100644
--- a/ojluni/src/main/java/java/security/Permission.java
+++ b/ojluni/src/main/java/java/security/Permission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/Permissions.java b/ojluni/src/main/java/java/security/Permissions.java
index de5d451..7411e06 100644
--- a/ojluni/src/main/java/java/security/Permissions.java
+++ b/ojluni/src/main/java/java/security/Permissions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/PrivilegedAction.java b/ojluni/src/main/java/java/security/PrivilegedAction.java
index ab39f98..bef7e44 100644
--- a/ojluni/src/main/java/java/security/PrivilegedAction.java
+++ b/ojluni/src/main/java/java/security/PrivilegedAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java b/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java
index 87e4209..bae883e 100644
--- a/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java
+++ b/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/SecurityPermission.java b/ojluni/src/main/java/java/security/SecurityPermission.java
index 432ee4b..7d2ec47 100644
--- a/ojluni/src/main/java/java/security/SecurityPermission.java
+++ b/ojluni/src/main/java/java/security/SecurityPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/Signature.java b/ojluni/src/main/java/java/security/Signature.java
index 730803f..7e9f5a8 100644
--- a/ojluni/src/main/java/java/security/Signature.java
+++ b/ojluni/src/main/java/java/security/Signature.java
@@ -99,106 +99,142 @@
*
* <p> Android provides the following {@code Signature} algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>DSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DSAwithSHA1</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DSS</td>
- * <td>1–19</td>
- * </tr>
- * <tr>
- * <td>ECDSA</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>ECDSAwithSHA1</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>MD2withRSA</td>
- * <td>1–3</td>
- * </tr>
- * <tr>
- * <td>MD4withRSA</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>MD5withRSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>MD5withRSA/ISO9796-2</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>NONEwithDSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>NONEwithECDSA</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>NONEwithRSA</td>
- * <td>17+</td>
- * </tr>
- * <tr>
- * <td>RSASSA-PSS</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>SHA1withDSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA1withECDSA</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>SHA1withRSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA1withRSA/ISO9796-2</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>SHA256withECDSA</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>SHA256withRSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA384withECDSA</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>SHA384withRSA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>SHA512withECDSA</td>
- * <td>11+</td>
- * </tr>
- * <tr>
- * <td>SHA512withRSA</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>DSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DSAwithSHA1</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DSS</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>ECDSA</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>ECDSAwithSHA1</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>MD2withRSA</td>
+ * <td>1-3</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>MD4withRSA</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>MD5withRSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>MD5withRSA/ISO9796-2</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>NONEwithDSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>NONEwithECDSA</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>NONEwithRSA</td>
+ * <td>17+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>RSASSA-PSS</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>SHA1withDSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA1withECDSA</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA1withRSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>SHA1withRSA/ISO9796-2</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>SHA1withRSA/PSS</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA224withDSA</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA224withECDSA</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA224withRSA</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA224withRSA/PSS</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA256withDSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA256withECDSA</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA256withRSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA256withRSA/PSS</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA384withECDSA</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA384withRSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA384withRSA/PSS</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA512withECDSA</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA512withRSA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>SHA512withRSA/PSS</td>
+ * <td>23+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/UnresolvedPermission.java b/ojluni/src/main/java/java/security/UnresolvedPermission.java
index dec952b..6d97fbe 100644
--- a/ojluni/src/main/java/java/security/UnresolvedPermission.java
+++ b/ojluni/src/main/java/java/security/UnresolvedPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/cert/CertPathBuilder.java b/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
index da5e322..fd6cdc8 100644
--- a/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
+++ b/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
@@ -68,18 +68,18 @@
*
* <p> Android provides the following {@code CertPathBuilder} algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>PKIX</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>PKIX</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* This algorithm is described in the <a href=
diff --git a/ojluni/src/main/java/java/security/cert/CertPathValidator.java b/ojluni/src/main/java/java/security/cert/CertPathValidator.java
index 40adafe..3a4b053 100644
--- a/ojluni/src/main/java/java/security/cert/CertPathValidator.java
+++ b/ojluni/src/main/java/java/security/cert/CertPathValidator.java
@@ -70,18 +70,18 @@
*
* <p> Android provides the following {@code CertPathValidator} algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>PKIX</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>PKIX</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* This algorithm is described in the <a href=
diff --git a/ojluni/src/main/java/java/security/cert/CertStore.java b/ojluni/src/main/java/java/security/cert/CertStore.java
index add36cd..047af77 100644
--- a/ojluni/src/main/java/java/security/cert/CertStore.java
+++ b/ojluni/src/main/java/java/security/cert/CertStore.java
@@ -62,18 +62,18 @@
*
* <p> Android provides the following <code>CertStore</code> types:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>Collection</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>Collection</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* This type is described in the <a href=
diff --git a/ojluni/src/main/java/java/security/cert/CertificateFactory.java b/ojluni/src/main/java/java/security/cert/CertificateFactory.java
index e82a579..e74ff0a 100644
--- a/ojluni/src/main/java/java/security/cert/CertificateFactory.java
+++ b/ojluni/src/main/java/java/security/cert/CertificateFactory.java
@@ -93,18 +93,18 @@
*
* <p> Android provides the following <code>CertificateFactory</code> types:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>X.509</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>X.509</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
* </table>
* and the following <code>CertPath</code> encodings:
* <table>
diff --git a/ojluni/src/main/java/java/util/regex/MatchResult.java b/ojluni/src/main/java/java/util/regex/MatchResult.java
index 9b52331..4f42eae 100644
--- a/ojluni/src/main/java/java/util/regex/MatchResult.java
+++ b/ojluni/src/main/java/java/util/regex/MatchResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,9 +77,9 @@
public int start(int group);
/**
- * Returns the offset after the last character matched. </p>
+ * Returns the offset after the last character matched.
*
- * @return @return The offset after the last character matched
+ * @return The offset after the last character matched
*
* @throws IllegalStateException
* If no match has yet been attempted,
diff --git a/ojluni/src/main/java/java/util/regex/Matcher.java b/ojluni/src/main/java/java/util/regex/Matcher.java
index 3d79ba7..9805dde 100644
--- a/ojluni/src/main/java/java/util/regex/Matcher.java
+++ b/ojluni/src/main/java/java/util/regex/Matcher.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/crypto/Cipher.java b/ojluni/src/main/java/javax/crypto/Cipher.java
index ea88f04..c2a2183 100644
--- a/ojluni/src/main/java/javax/crypto/Cipher.java
+++ b/ojluni/src/main/java/javax/crypto/Cipher.java
@@ -134,494 +134,87 @@
* </pre>
* <p> Android provides the following <code>Cipher</code> transformations:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tr>
- * <td>AES/CBC/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CBC/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CBC/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CTR/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CTR/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CTR/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CTS/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CTS/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/CTS/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/ECB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/ECB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/ECB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/OFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/OFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AES/OFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>ARCFOUR/ECB/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CBC/ISO10126Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CBC/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CBC/PKCS5Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CFB/ISO10126Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CFB/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CFB/PKCS5Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CTR/ISO10126Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CTR/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CTR/PKCS5Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CTS/ISO10126Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CTS/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/CTS/PKCS5Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/ECB/ISO10126Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/ECB/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/ECB/PKCS5Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/OFB/ISO10126Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/OFB/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>BLOWFISH/OFB/PKCS5Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>DES/CBC/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CBC/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CBC/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CTR/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CTR/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CTR/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CTS/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CTS/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/CTS/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/ECB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/ECB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/ECB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/OFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/OFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DES/OFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CBC/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CBC/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CBC/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CTR/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CTR/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CTR/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CTS/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CTS/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/CTS/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/ECB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/ECB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/ECB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/OFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/OFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede/OFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CBC/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CBC/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CBC/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CTR/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CTR/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CTR/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CTS/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CTS/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/CTS/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/ECB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/ECB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/ECB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/OFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/OFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES/OFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CBC/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CBC/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CBC/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CTR/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CTR/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CTR/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CTS/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CTS/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/CTS/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/ECB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/ECB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/ECB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/OFB/ISO10126Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/OFB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDESede/OFB/PKCS5Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>RC4/ECB/NoPadding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>RSA/ECB/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>RSA/ECB/OAEPPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>RSA/ECB/OAEPwithSHA-1andMGF1Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>RSA/ECB/OAEPwithSHA-256andMGF1Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>RSA/ECB/PKCS1Padding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>RSA/NONE/NoPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>RSA/NONE/OAEPPadding</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>RSA/NONE/OAEPwithSHA-1andMGF1Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>RSA/NONE/OAEPwithSHA-256andMGF1Padding</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>RSA/NONE/PKCS1Padding</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Modes</th>
+ * <th>Paddings</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td rowspan="2">AES</td>
+ * <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ * <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>GCM</td>
+ * <td>NOPADDING</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="2">AES_128</td>
+ * <td>CBC<br>ECB</td>
+ * <td>NoPadding<br>PKCS5Padding</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>GCM</td>
+ * <td>NoPadding</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="2">AES_256</td>
+ * <td>CBC<br>ECB</td>
+ * <td>NoPadding<br>PKCS5Padding</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>GCM</td>
+ * <td>NoPadding</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>ARC4</td>
+ * <td>ECB</td>
+ * <td>NoPadding</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>BLOWFISH</td>
+ * <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ * <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>DES</td>
+ * <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ * <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DESede</td>
+ * <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ * <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="3">RSA</td>
+ * <td rowspan="3">ECB<br>NONE</td>
+ * <td>NoPadding<br>OAEPPadding<br>PKCS1Padding</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>OAEPwithSHA-1andMGF1Padding<br>OAEPwithSHA-256andMGF1Padding</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>OAEPwithSHA-224andMGF1Padding<br>OAEPwithSHA-384andMGF1Padding<br>OAEPwithSHA-512andMGF1Padding</td>
+ * <td>23+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These transformations are described in the
diff --git a/ojluni/src/main/java/javax/crypto/CipherOutputStream.java b/ojluni/src/main/java/javax/crypto/CipherOutputStream.java
index 6b8d273..370f7af 100644
--- a/ojluni/src/main/java/javax/crypto/CipherOutputStream.java
+++ b/ojluni/src/main/java/javax/crypto/CipherOutputStream.java
@@ -210,6 +210,8 @@
obuffer = cipher.doFinal();
} catch (IllegalBlockSizeException | BadPaddingException e) {
obuffer = null;
+ // Android-added: Throw an exception when the underlying cipher does. http://b/36636576
+ throw new IOException(e);
}
try {
flush();
diff --git a/ojluni/src/main/java/javax/crypto/JceSecurity.java b/ojluni/src/main/java/javax/crypto/JceSecurity.java
index 72a6c31..073d827 100644
--- a/ojluni/src/main/java/javax/crypto/JceSecurity.java
+++ b/ojluni/src/main/java/javax/crypto/JceSecurity.java
@@ -73,7 +73,8 @@
private JceSecurity() {
}
- /* BEGIN Android-changed
+ // BEGIN Android-changed
+ /*
static {
try {
AccessController.doPrivileged(
@@ -91,7 +92,8 @@
"Can not initialize cryptographic mechanism", e);
}
}
- END Android-changed */
+ */
+ // END Android-changed
static Instance getInstance(String type, Class<?> clazz, String algorithm,
String provider) throws NoSuchAlgorithmException,
@@ -199,9 +201,8 @@
// return whether this provider is properly signed and can be used by JCE
static boolean canUseProvider(Provider p) {
- /* BEGIN Android-changed
- return getVerificationResult(p) == null;
- */
+ // BEGIN Android-changed
+ // return getVerificationResult(p) == null;
return true;
// END Android-changed
}
diff --git a/ojluni/src/main/java/javax/crypto/KeyAgreement.java b/ojluni/src/main/java/javax/crypto/KeyAgreement.java
index dab71f5..8a0b1c1 100644
--- a/ojluni/src/main/java/javax/crypto/KeyAgreement.java
+++ b/ojluni/src/main/java/javax/crypto/KeyAgreement.java
@@ -59,22 +59,22 @@
*
* <p> Android provides the following <code>KeyAgreement</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>DH</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>ECDH</td>
- * <td>11+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>DH</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>ECDH</td>
+ * <td>11+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* This algorithm is described in the <a href=
diff --git a/ojluni/src/main/java/javax/crypto/KeyGenerator.java b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
index cb3ad69..8a54e5c 100644
--- a/ojluni/src/main/java/javax/crypto/KeyGenerator.java
+++ b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
@@ -88,70 +88,70 @@
*
* <p> Android provides the following <code>KeyGenerator</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>AES</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>AESWRAP</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>ARC4</td>
- * <td>14+</td>
- * </tr>
- * <tr>
- * <td>Blowfish</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>DES</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESedeWRAP</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>HmacMD5</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA1</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA224</td>
- * <td>1–8,22+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA256</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA384</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA512</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>RC4</td>
- * <td>10–13</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>AES</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>AESWRAP</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>ARC4</td>
+ * <td>14+</td>
+ * </tr>
+ * <tr>
+ * <td>BLOWFISH</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>DES</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DESede</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DESedeWRAP</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>HmacMD5</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA1</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA224</td>
+ * <td>1-8,22+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA256</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA384</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA512</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>RC4</td>
+ * <td>10-13</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/javax/crypto/Mac.java b/ojluni/src/main/java/javax/crypto/Mac.java
index bee46cd..2315db7 100644
--- a/ojluni/src/main/java/javax/crypto/Mac.java
+++ b/ojluni/src/main/java/javax/crypto/Mac.java
@@ -56,76 +56,92 @@
* e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is
* specified in RFC 2104.
*
- * <p> Android provides the following <code>Mac</code> algorithms
+ * <p> Android provides the following <code>Mac</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>DESedeMAC</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DESedeMAC/CFB8</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DESedeMAC64</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DESMAC</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DESMAC/CFB8</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>DESwithISO9797</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>HmacMD5</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA1</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA224</td>
- * <td>1–8, 22+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA256</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA384</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA512</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>ISO9797ALG3MAC</td>
- * <td>1–8</td>
- * </tr>
- * <tr>
- * <td>PBEwithHmacSHA</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithHmacSHA1</td>
- * <td>1+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr class="deprecated">
+ * <td>DESMAC</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DESMAC/CFB8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DESedeMAC</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DESedeMAC/CFB8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DESedeMAC64</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>DESwithISO9797</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>HmacMD5</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA1</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA224</td>
+ * <td>1-8,22+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA256</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA384</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA512</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>ISO9797ALG3MAC</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA1</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA224</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA384</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA512</td>
+ * <td>26+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the
diff --git a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
index 0c323dd..c1358c2 100644
--- a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
+++ b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
@@ -60,138 +60,194 @@
*
* <p> Android provides the following <code>SecretKeyFactory</code> algorithms:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>AES</td>
- * <td>23+</td>
- * </tr>
- * <tr>
- * <td>DES</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>DESede</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA1</td>
- * <td>23+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA224</td>
- * <td>23+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA256</td>
- * <td>23+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA384</td>
- * <td>23+</td>
- * </tr>
- * <tr>
- * <td>HmacSHA512</td>
- * <td>23+</td>
- * </tr>
- * <tr>
- * <td>PBEwithHmacSHA1</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5and128BITAES-CBC-OPENSSL</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5and192BITAES-CBC-OPENSSL</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5and256BITAES-CBC-OPENSSL</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andDES</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithMD5andRC2</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andDES</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA1andRC2</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA256and128BITAES-CBC-BC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA256and192BITAES-CBC-BC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHA256and256BITAES-CBC-BC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand128BITAES-CBC-BC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand128BITRC2-CBC</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand128BITRC4</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand192BITAES-CBC-BC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand2-KEYTRIPLEDES-CBC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand256BITAES-CBC-BC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand3-KEYTRIPLEDES-CBC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand40BITRC2-CBC</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAand40BITRC4</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>PBEwithSHAandTWOFISH-CBC</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>PBKDF2withHmacSHA1</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>PBKDF2withHmacSHA1and8BIT</td>
- * <td>19+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>AES</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>DES</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DESede</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA1</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA224</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA256</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA384</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>HmacSHA512</td>
+ * <td>23+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA1</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA1AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA1AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA224AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA224AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA256AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA256AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA384AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA384AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA512AndAES_128</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithHmacSHA512AndAES_256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithMD5AND128BITAES-CBC-OPENSSL</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithMD5AND192BITAES-CBC-OPENSSL</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithMD5AND256BITAES-CBC-OPENSSL</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithMD5ANDDES</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithMD5ANDRC2</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHA1ANDDES</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHA1ANDRC2</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHA256AND128BITAES-CBC-BC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHA256AND192BITAES-CBC-BC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHA256AND256BITAES-CBC-BC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND128BITAES-CBC-BC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND128BITRC2-CBC</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND128BITRC4</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND192BITAES-CBC-BC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND2-KEYTRIPLEDES-CBC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND256BITAES-CBC-BC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND3-KEYTRIPLEDES-CBC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND40BITRC2-CBC</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAAND40BITRC4</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>PBEwithSHAANDTWOFISH-CBC</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>PBKDF2withHmacSHA1</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>PBKDF2withHmacSHA1And8BIT</td>
+ * <td>19+</td>
+ * </tr>
+ * <tr>
+ * <td>PBKDF2withHmacSHA224</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBKDF2withHmacSHA256</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBKDF2withHmacSHA384</td>
+ * <td>26+</td>
+ * </tr>
+ * <tr>
+ * <td>PBKDF2withHmacSHA512</td>
+ * <td>26+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java b/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
index b9fe920..f6abafa 100644
--- a/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
+++ b/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
import java.security.cert.Certificate;
import java.security.Principal;
import java.security.cert.X509Certificate;
-import javax.security.auth.x500.X500Principal;
/**
* This event indicates that an SSL handshake completed on a given
@@ -186,8 +185,7 @@
// if the provider does not support it, fallback to peer certs.
// return the X500Principal of the end-entity cert.
Certificate[] certs = getPeerCertificates();
- principal = (X500Principal)
- ((X509Certificate)certs[0]).getSubjectX500Principal();
+ principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
}
return principal;
}
@@ -216,7 +214,7 @@
// return the X500Principal of the end-entity cert.
Certificate[] certs = getLocalCertificates();
if (certs != null) {
- principal = (X500Principal)
+ principal =
((X509Certificate)certs[0]).getSubjectX500Principal();
}
}
diff --git a/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java b/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
index d2f504f..49b3163 100644
--- a/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
+++ b/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index de1c89d..9660643 100644
--- a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
+++ b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
import java.net.HttpURLConnection;
import java.security.Principal;
import java.security.cert.X509Certificate;
-import javax.security.auth.x500.X500Principal;
/**
* <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
@@ -145,8 +144,7 @@
throws SSLPeerUnverifiedException {
java.security.cert.Certificate[] certs = getServerCertificates();
- return ((X500Principal)
- ((X509Certificate)certs[0]).getSubjectX500Principal());
+ return ((X509Certificate)certs[0]).getSubjectX500Principal();
}
/**
@@ -174,8 +172,7 @@
java.security.cert.Certificate[] certs = getLocalCertificates();
if (certs != null) {
- return ((X500Principal)
- ((X509Certificate)certs[0]).getSubjectX500Principal());
+ return ((X509Certificate)certs[0]).getSubjectX500Principal();
} else {
return null;
}
diff --git a/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java b/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
index 70ea99f..2199c9f 100644
--- a/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,22 @@
* type of key material for use by secure sockets. The key
* material is based on a KeyStore and/or provider specific sources.
*
+ * <p> Android provides the following <code>KeyManagerFactory</code> algorithms:
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>PKIX</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
* @since 1.4
* @see KeyManager
*/
@@ -53,21 +69,18 @@
* Obtains the default KeyManagerFactory algorithm name.
*
* <p>The default algorithm can be changed at runtime by setting
- * the value of the "ssl.KeyManagerFactory.algorithm" security
- * property (set in the Java security properties file or by calling
- * {@link java.security.Security#setProperty(java.lang.String,
- * java.lang.String)})
- * to the desired algorithm name.
+ * the value of the {@code ssl.KeyManagerFactory.algorithm}
+ * security property to the desired algorithm name.
*
- * @see java.security.Security#setProperty(java.lang.String,
- * java.lang.String)
- * @return the default algorithm name as specified in the
- * Java security properties, or an implementation-specific
- * default if no such property exists.
+ * @see java.security.Security security properties
+ * @return the default algorithm name as specified by the
+ * {@code ssl.KeyManagerFactory.algorithm} security property, or an
+ * implementation-specific default if no such property exists.
*/
public final static String getDefaultAlgorithm() {
String type;
type = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ @Override
public String run() {
return Security.getProperty(
"ssl.KeyManagerFactory.algorithm");
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLContext.java b/ojluni/src/main/java/javax/net/ssl/SSLContext.java
index fa8a3af..71cfc23 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLContext.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,42 +39,42 @@
*
* <p> Android provides the following <code>SSLContext</code> protocols:
* <table>
- * <thead>
- * <tr>
- * <th>Name</th>
- * <th>Supported (API Levels)</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>Default</td>
- * <td>10+</td>
- * </tr>
- * <tr class="deprecated">
- * <td>SSL</td>
- * <td>10–TBD</td>
- * </tr>
- * <tr class="deprecated">
- * <td>SSLv3</td>
- * <td>10–TBD</td>
- * </tr>
- * <tr>
- * <td>TLS</td>
- * <td>1+</td>
- * </tr>
- * <tr>
- * <td>TLSv1</td>
- * <td>10+</td>
- * </tr>
- * <tr>
- * <td>TLSv1.1</td>
- * <td>16+</td>
- * </tr>
- * <tr>
- * <td>TLSv1.2</td>
- * <td>16+</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>Default</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>SSL</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr class="deprecated">
+ * <td>SSLv3</td>
+ * <td>10-25</td>
+ * </tr>
+ * <tr>
+ * <td>TLS</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1</td>
+ * <td>10+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.1</td>
+ * <td>16+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.2</td>
+ * <td>16+</td>
+ * </tr>
+ * </tbody>
* </table>
*
* This protocol is described in the <a href=
@@ -255,11 +255,11 @@
*
* @return the new <code>SSLContext</code> object.
*
- * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi
+ * @throws NoSuchAlgorithmException if a SSLContextSpi
* implementation for the specified protocol is not available
* from the specified Provider object.
*
- * @throws IllegalArgumentException if the provider name is null.
+ * @throws IllegalArgumentException if the provider is null.
* @throws NullPointerException if protocol is null.
*
* @see java.security.Provider
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java b/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java
index e4def55..269ed85 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package javax.net.ssl;
-import java.util.*;
import java.security.*;
/**
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
index 2bf28b1..26dc64c 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -211,7 +211,7 @@
* that the source buffer has enough room to hold a record (enlarging if
* necessary), and then obtain more inbound data.
*
- * <pre>
+ * <pre>{@code
* SSLEngineResult r = engine.unwrap(src, dst);
* switch (r.getStatus()) {
* BUFFER_OVERFLOW:
@@ -238,7 +238,7 @@
* break;
* // other cases: CLOSED, OK.
* }
- * </pre>
+ * }</pre>
*
* <P>
* Unlike <code>SSLSocket</code>, all methods of SSLEngine are
@@ -329,7 +329,6 @@
* is saved. All future delegated tasks will be processed using this
* context: that is, all access control decisions will be made using the
* context captured at engine creation.
- * <P>
* <HR>
*
* <B>Concurrency Notes</B>:
@@ -345,7 +344,7 @@
* out-of-order, unexpected or fatal results may occur.
* <P>
* For example:
- * <P>
+ *
* <pre>
* synchronized (outboundLock) {
* sslEngine.wrap(src, dst);
@@ -1088,7 +1087,7 @@
* <blockquote><pre>
* {@link #wrap(ByteBuffer [], int, int, ByteBuffer)
* engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);}
- * </pre</blockquote>
+ * </pre></blockquote>
*
* @param src
* a <code>ByteBuffer</code> containing outbound application data
@@ -1124,7 +1123,7 @@
* <blockquote><pre>
* {@link #wrap(ByteBuffer [], int, int, ByteBuffer)
* engine.wrap(srcs, 0, srcs.length, dst);}
- * </pre</blockquote>
+ * </pre></blockquote>
*
* @param srcs
* an array of <code>ByteBuffers</code> containing the
@@ -1243,7 +1242,7 @@
* <blockquote><pre>
* {@link #unwrap(ByteBuffer, ByteBuffer [], int, int)
* engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);}
- * </pre</blockquote>
+ * </pre></blockquote>
*
* @param src
* a <code>ByteBuffer</code> containing inbound network data.
@@ -1279,7 +1278,7 @@
* <blockquote><pre>
* {@link #unwrap(ByteBuffer, ByteBuffer [], int, int)
* engine.unwrap(src, dsts, 0, dsts.length);}
- * </pre</blockquote>
+ * </pre></blockquote>
*
* @param src
* a <code>ByteBuffer</code> containing inbound network data.
@@ -1860,15 +1859,19 @@
*
* <p>This means:
* <ul>
- * <li>if <code>params.getCipherSuites()</code> is non-null,
- * <code>setEnabledCipherSuites()</code> is called with that value
- * <li>if <code>params.getProtocols()</code> is non-null,
- * <code>setEnabledProtocols()</code> is called with that value
- * <li>if <code>params.getNeedClientAuth()</code> or
- * <code>params.getWantClientAuth()</code> return <code>true</code>,
- * <code>setNeedClientAuth(true)</code> and
- * <code>setWantClientAuth(true)</code> are called, respectively;
- * otherwise <code>setWantClientAuth(false)</code> is called.
+ * <li>If {@code params.getCipherSuites()} is non-null,
+ * {@code setEnabledCipherSuites()} is called with that value.</li>
+ * <li>If {@code params.getProtocols()} is non-null,
+ * {@code setEnabledProtocols()} is called with that value.</li>
+ * <li>If {@code params.getNeedClientAuth()} or
+ * {@code params.getWantClientAuth()} return {@code true},
+ * {@code setNeedClientAuth(true)} and
+ * {@code setWantClientAuth(true)} are called, respectively;
+ * otherwise {@code setWantClientAuth(false)} is called.</li>
+ * <li>If {@code params.getServerNames()} is non-null, the engine will
+ * configure its server names with that value.</li>
+ * <li>If {@code params.getSNIMatchers()} is non-null, the engine will
+ * configure its SNI matchers with that value.</li>
* </ul>
*
* @param params the parameters
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java b/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java
index dd63ea4..af42f2b 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -173,7 +173,7 @@
*
* @throws IllegalArgumentException
* if the <code>status</code> or <code>handshakeStatus</code>
- * arguments are null, or if <<code>bytesConsumed</code> or
+ * arguments are null, or if <code>bytesConsumed</code> or
* <code>bytesProduced</code> is negative.
*/
public SSLEngineResult(Status status, HandshakeStatus handshakeStatus,
@@ -230,6 +230,7 @@
/**
* Returns a String representation of this object.
*/
+ @Override
public String toString() {
return ("Status = " + status +
" HandshakeStatus = " + handshakeStatus +
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java b/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java
index b6b4087..e613e0f 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
/**
* Constructs an exception reporting that the SSL peer's
- * identity has not been verifiied.
+ * identity has not been verified.
*
* @param reason describes the problem.
*/
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java b/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
index b7a6c3d..50efe8d 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -484,15 +484,19 @@
*
* <p>This means:
* <ul>
- * <li>if <code>params.getCipherSuites()</code> is non-null,
- * <code>setEnabledCipherSuites()</code> is called with that value
- * <li>if <code>params.getProtocols()</code> is non-null,
- * <code>setEnabledProtocols()</code> is called with that value
- * <li>if <code>params.getNeedClientAuth()</code> or
- * <code>params.getWantClientAuth()</code> return <code>true</code>,
- * <code>setNeedClientAuth(true)</code> and
- * <code>setWantClientAuth(true)</code> are called, respectively;
- * otherwise <code>setWantClientAuth(false)</code> is called.
+ * <li>If {@code params.getCipherSuites()} is non-null,
+ * {@code setEnabledCipherSuites()} is called with that value.</li>
+ * <li>If {@code params.getProtocols()} is non-null,
+ * {@code setEnabledProtocols()} is called with that value.</li>
+ * <li>If {@code params.getNeedClientAuth()} or
+ * {@code params.getWantClientAuth()} return {@code true},
+ * {@code setNeedClientAuth(true)} and
+ * {@code setWantClientAuth(true)} are called, respectively;
+ * otherwise {@code setWantClientAuth(false)} is called.</li>
+ * <li>If {@code params.getServerNames()} is non-null, the socket will
+ * configure its server names with that value.</li>
+ * <li>If {@code params.getSNIMatchers()} is non-null, the socket will
+ * configure its SNI matchers with that value.</li>
* </ul>
*
* @param params the parameters
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java b/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
index 7809c93..a480c60 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -192,23 +192,27 @@
new SocketException(reason.toString()).initCause(reason);
}
+ @Override
public ServerSocket createServerSocket() throws IOException {
return throwException();
}
+ @Override
public ServerSocket createServerSocket(int port)
throws IOException
{
return throwException();
}
+ @Override
public ServerSocket createServerSocket(int port, int backlog)
throws IOException
{
return throwException();
}
+ @Override
public ServerSocket
createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException
@@ -216,10 +220,12 @@
return throwException();
}
+ @Override
public String [] getDefaultCipherSuites() {
return new String[0];
}
+ @Override
public String [] getSupportedCipherSuites() {
return new String[0];
}
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSession.java b/ojluni/src/main/java/javax/net/ssl/SSLSession.java
index 93f0667..d98edf0 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSession.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSession.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package javax.net.ssl;
-import java.net.InetAddress;
import java.security.Principal;
/**
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java b/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java
index 61f1ddc..b6f6fb6 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,7 +90,7 @@
* @param seconds the new session timeout limit in seconds; zero means
* there is no limit.
*
- * @exception IllegalArgumentException if the timeout specified is < 0.
+ * @exception IllegalArgumentException if the timeout specified is {@code < 0}.
* @see #getSessionTimeout
*/
public void setSessionTimeout(int seconds)
@@ -122,7 +122,7 @@
*
* @param size the new session cache size limit; zero means there is no
* limit.
- * @exception IllegalArgumentException if the specified size is < 0.
+ * @exception IllegalArgumentException if the specified size is {@code < 0}.
* @see #getSessionCacheSize
*/
public void setSessionCacheSize(int size)
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
index 1b6a69c..f2037b4 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
import java.io.IOException;
import java.net.*;
-import java.util.Enumeration;
-import java.util.Vector;
/**
@@ -81,7 +79,7 @@
* </UL>
*
* <P>If handshaking fails for any reason, the <code>SSLSocket</code>
- * is closed, and no futher communications can be done.
+ * is closed, and no further communications can be done.
*
* <P>There are two groups of cipher suites which you will need to know
* about when managing cipher suites: <UL>
@@ -1358,15 +1356,19 @@
*
* <p>This means:
* <ul>
- * <li>if <code>params.getCipherSuites()</code> is non-null,
- * <code>setEnabledCipherSuites()</code> is called with that value
- * <li>if <code>params.getProtocols()</code> is non-null,
- * <code>setEnabledProtocols()</code> is called with that value
- * <li>if <code>params.getNeedClientAuth()</code> or
- * <code>params.getWantClientAuth()</code> return <code>true</code>,
- * <code>setNeedClientAuth(true)</code> and
- * <code>setWantClientAuth(true)</code> are called, respectively;
- * otherwise <code>setWantClientAuth(false)</code> is called.
+ * <li>If {@code params.getCipherSuites()} is non-null,
+ * {@code setEnabledCipherSuites()} is called with that value.</li>
+ * <li>If {@code params.getProtocols()} is non-null,
+ * {@code setEnabledProtocols()} is called with that value.</li>
+ * <li>If {@code params.getNeedClientAuth()} or
+ * {@code params.getWantClientAuth()} return {@code true},
+ * {@code setNeedClientAuth(true)} and
+ * {@code setWantClientAuth(true)} are called, respectively;
+ * otherwise {@code setWantClientAuth(false)} is called.</li>
+ * <li>If {@code params.getServerNames()} is non-null, the socket will
+ * configure its server names with that value.</li>
+ * <li>If {@code params.getSNIMatchers()} is non-null, the socket will
+ * configure its SNI matchers with that value.</li>
* </ul>
*
* @param params the parameters
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java b/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
index 6b257f5..f1d7057 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -206,8 +206,7 @@
* @throws NullPointerException if the parameter s is null
*/
public abstract Socket createSocket(Socket s, String host,
- int port, boolean autoClose)
- throws IOException;
+ int port, boolean autoClose) throws IOException;
}
@@ -225,18 +224,21 @@
new SocketException(reason.toString()).initCause(reason);
}
+ @Override
public Socket createSocket()
throws IOException
{
return throwException();
}
+ @Override
public Socket createSocket(String host, int port)
throws IOException
{
return throwException();
}
+ @Override
public Socket createSocket(Socket s, String host,
int port, boolean autoClose)
throws IOException
@@ -244,12 +246,14 @@
return throwException();
}
+ @Override
public Socket createSocket(InetAddress address, int port)
throws IOException
{
return throwException();
}
+ @Override
public Socket createSocket(String host, int port,
InetAddress clientAddress, int clientPort)
throws IOException
@@ -257,6 +261,7 @@
return throwException();
}
+ @Override
public Socket createSocket(InetAddress address, int port,
InetAddress clientAddress, int clientPort)
throws IOException
@@ -264,10 +269,12 @@
return throwException();
}
+ @Override
public String [] getDefaultCipherSuites() {
return new String[0];
}
+ @Override
public String [] getSupportedCipherSuites() {
return new String[0];
}
diff --git a/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java b/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
index aa5baa7..2a223b0 100644
--- a/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,22 @@
* type of trust material for use by secure sockets. The trust
* material is based on a KeyStore and/or provider specific sources.
*
+ * <p> Android provides the following <code>TrustManagerFactory</code> algorithms:
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Algorithm</th>
+ * <th>Supported API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>PKIX</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
* @since 1.4
* @see TrustManager
*/
@@ -53,18 +69,18 @@
* Obtains the default TrustManagerFactory algorithm name.
*
* <p>The default TrustManager can be changed at runtime by setting
- * the value of the "ssl.TrustManagerFactory.algorithm" security
- * property (set in the Java security properties file or by calling
- * {@link java.security.Security#setProperty(String, String) })
- * to the desired algorithm name.
+ * the value of the {@code ssl.TrustManagerFactory.algorithm}
+ * security property to the desired algorithm name.
*
- * @return the default algorithm name as specified in the
- * Java security properties, or an implementation-specific default
- * if no such property exists.
+ * @see java.security.Security security properties
+ * @return the default algorithm name as specified by the
+ * {@code ssl.TrustManagerFactory.algorithm} security property, or an
+ * implementation-specific default if no such property exists.
*/
public final static String getDefaultAlgorithm() {
String type;
type = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ @Override
public String run() {
return Security.getProperty(
"ssl.TrustManagerFactory.algorithm");
diff --git a/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java b/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java
index 3fcf222..69ab91a 100644
--- a/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java
+++ b/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package javax.net.ssl;
-import java.security.KeyManagementException;
import java.security.PrivateKey;
import java.security.Principal;
import java.security.cert.X509Certificate;
@@ -41,7 +40,7 @@
* <UL>
* <LI> determine the set of aliases that are available for negotiations
* based on the criteria presented,
- * <LI> select the <ITALIC> best alias </ITALIC> based on
+ * <LI> select the <i> best alias</i> based on
* the criteria presented, and
* <LI> obtain the corresponding key material for given aliases.
* </UL>
diff --git a/ojluni/src/main/java/javax/security/auth/AuthPermission.java b/ojluni/src/main/java/javax/security/auth/AuthPermission.java
index 82a7eb3..651e9a3 100644
--- a/ojluni/src/main/java/javax/security/auth/AuthPermission.java
+++ b/ojluni/src/main/java/javax/security/auth/AuthPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java b/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
index a49032d..ca52a1b2 100644
--- a/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
+++ b/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java b/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
index 6352927..8e07d4b 100644
--- a/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
+++ b/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/sun/net/util/IPAddressUtil.java b/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
index e43e386..7ca0f12 100644
--- a/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
+++ b/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
@@ -48,7 +48,8 @@
long val;
try {
switch(s.length) {
- /* BEGIN Android-changed
+ // BEGIN Android-removed
+ /*
case 1:
// When only one part is given, the value is stored directly in
// the network address without any byte rearrangement.
@@ -97,7 +98,9 @@
return null;
res[2] = (byte) ((val >> 8) & 0xff);
res[3] = (byte) (val & 0xff);
- break; */
+ break;
+ */
+ // END Android-removed
case 4:
/*
* When four parts are specified, each is interpreted as a
diff --git a/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java b/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java
index 3158215..762df01 100644
--- a/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java
+++ b/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java
@@ -361,7 +361,9 @@
return dc;
}
- /** @hide */
+ /*
+ * Android-added: for testing and internal use.
+ */
@Override
public final FileDescriptor getFileDescriptor$() {
return dc.fd;
diff --git a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
index 2b5615d..de78c68 100644
--- a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
@@ -929,12 +929,14 @@
return null;
if (filesize < position + size) { // Extend file size
- /* BEGIN Android-changed
+ // BEGIN Android-changed
+ /*
if (!writable) {
throw new IOException("Channel not open for writing " +
"- cannot extend file to required size");
}
- END Android-changed */
+ */
+ // END Android-changed
int rv = 0;
do {
// BEGIN Android-changed
diff --git a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
index 10f6b25..aa6d834 100644
--- a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
@@ -453,6 +453,9 @@
return !sc.isOutputOpen();
}
+ /*
+ * Android-added: for testing and internal use.
+ */
@Override
public FileDescriptor getFileDescriptor$() {
return sc.getFD();
diff --git a/ojluni/src/main/java/sun/reflect/Reflection.java b/ojluni/src/main/java/sun/reflect/Reflection.java
index f866d3e..a3fa56d 100644
--- a/ojluni/src/main/java/sun/reflect/Reflection.java
+++ b/ojluni/src/main/java/sun/reflect/Reflection.java
@@ -75,10 +75,9 @@
return true;
}
- /* BEGIN Android-changed
- if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {*/
+ // Android-changed
+ // if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
if (!Modifier.isPublic(memberClass.getAccessFlags())) {
- // END Android-changed
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
if (!isSameClassPackage) {
diff --git a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
index 20d7495..b78fdf9 100644
--- a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
+++ b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
@@ -64,9 +64,8 @@
byte[] encryptedDigest;
Timestamp timestamp;
private boolean hasTimestamp = true;
- /* BEGIN Android-removed
- private static final Debug debug = Debug.getInstance("jar");
- * END Android-removed */
+ // Android-removed
+ // private static final Debug debug = Debug.getInstance("jar");
PKCS9Attributes authenticatedAttributes;
PKCS9Attributes unauthenticatedAttributes;
@@ -562,14 +561,16 @@
" is inapplicable");
}
- /* BEGIN Android-removed
+ // BEGIN Android-removed
+ /*
if (debug != null) {
debug.println();
debug.println("Detected signature timestamp (#" +
token.getSerialNumber() + ") generated on " + token.getDate());
debug.println();
}
- * END Android-removed */
+ */
+ // END Android-removed
}
public String toString() {
diff --git a/ojluni/src/main/java/sun/security/provider/X509Factory.java b/ojluni/src/main/java/sun/security/provider/X509Factory.java
index f894f89..4fa6ec2 100644
--- a/ojluni/src/main/java/sun/security/provider/X509Factory.java
+++ b/ojluni/src/main/java/sun/security/provider/X509Factory.java
@@ -25,24 +25,10 @@
package sun.security.provider;
-/* BEGIN Android-removed
-import java.io.*;
-import java.util.*;
- * END Android-removed */
import java.security.cert.*;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl;
-/* BEGIN Android-removed
-import sun.security.pkcs.PKCS7;
-import sun.security.provider.certpath.X509CertPath;
-import sun.security.provider.certpath.X509CertificatePair;
-import sun.security.util.DerValue;
- * END Android-removed */
import sun.security.util.Cache;
-/* BEGIN Android-removed
-import java.util.Base64;
-import sun.security.pkcs.ParsingException;
- * END Android-removed */
/**
* This class defines a certificate factory for X.509 v3 certificates &
@@ -63,15 +49,14 @@
* @see sun.security.x509.X509CRLImpl
*/
-// BEGIN Android-changed
-// Was: public class X509Factory extends CertificateFactorySpi {
+// Android-changed
+// public class X509Factory extends CertificateFactorySpi {
public class X509Factory {
-// END Android-changed
- /* BEGIN Android-removed
- public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
- public static final String END_CERT = "-----END CERTIFICATE-----";
- * END Android-removed */
+ // BEGIN Android-removed
+ // public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
+ // public static final String END_CERT = "-----END CERTIFICATE-----";
+ // END Android-removed
private static final int ENC_MAX_LENGTH = 4096 * 1024; // 4 MB MAX
@@ -80,7 +65,8 @@
private static final Cache<Object, X509CRLImpl> crlCache
= Cache.newSoftMemoryCache(750);
- /* BEGIN Android-removed
+ // BEGIN Android-removed
+ /*
/**
* Generates an X.509 certificate object and initializes it with
* the data read from the input stream <code>is</code>.
@@ -140,7 +126,8 @@
}
return read;
}
- * END Android-removed */
+ */
+ // END Android-removed
/**
* Return an interned X509CertImpl for the given certificate.
@@ -244,7 +231,8 @@
cache.put(key, value);
}
- /* BEGIN Android-removed
+ // BEGIN Android-removed
+ /*
/**
* Generates a <code>CertPath</code> object and initializes it with
* the data read from the <code>InputStream</code> inStream. The data
@@ -767,5 +755,6 @@
}
return tag;
}
- * END Android-removed */
+ */
+ // END Android-removed
}
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java b/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
index 680795c..0ad5387 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,40 +26,42 @@
package sun.security.provider.certpath;
import java.io.IOException;
-import java.util.Date;
-
+import java.math.BigInteger;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.Date;
-import sun.security.util.DerOutputStream;
+import sun.security.util.Debug;
+import sun.security.util.DerInputStream;
import sun.security.x509.SerialNumber;
-import sun.security.x509.KeyIdentifier;
import sun.security.x509.AuthorityKeyIdentifierExtension;
/**
* An adaptable X509 certificate selector for forward certification path
- * building.
+ * building. This selector overrides the default X509CertSelector matching
+ * rules for the subjectKeyIdentifier and serialNumber criteria, and adds
+ * additional rules for certificate validity.
*
* @since 1.7
*/
class AdaptableX509CertSelector extends X509CertSelector {
+
+ private static final Debug debug = Debug.getInstance("certpath");
+
// The start date of a validity period.
private Date startDate;
// The end date of a validity period.
private Date endDate;
- // Is subject key identifier sensitive?
- private boolean isSKIDSensitive = false;
+ // The subject key identifier
+ private byte[] ski;
- // Is serial number sensitive?
- private boolean isSNSensitive = false;
-
- AdaptableX509CertSelector() {
- super();
- }
+ // The serial number
+ private BigInteger serial;
/**
* Sets the criterion of the X509Certificate validity period.
@@ -86,51 +88,64 @@
}
/**
- * Parse the authority key identifier extension.
- *
- * If the keyIdentifier field of the extension is non-null, set the
- * subjectKeyIdentifier criterion. If the authorityCertSerialNumber
- * field is non-null, set the serialNumber criterion.
- *
- * Note that we will not set the subject criterion according to the
- * authorityCertIssuer field of the extension. The caller MUST set
- * the subject criterion before call match().
- *
- * @param akidext the authorityKeyIdentifier extension
+ * This selector overrides the subjectKeyIdentifier matching rules of
+ * X509CertSelector, so it throws IllegalArgumentException if this method
+ * is ever called.
*/
- void parseAuthorityKeyIdentifierExtension(
- AuthorityKeyIdentifierExtension akidext) throws IOException {
- if (akidext != null) {
- KeyIdentifier akid = (KeyIdentifier)akidext.get(
- AuthorityKeyIdentifierExtension.KEY_ID);
- if (akid != null) {
- // Do not override the previous setting for initial selection.
- if (isSKIDSensitive || getSubjectKeyIdentifier() == null) {
- DerOutputStream derout = new DerOutputStream();
- derout.putOctetString(akid.getIdentifier());
- super.setSubjectKeyIdentifier(derout.toByteArray());
+ @Override
+ public void setSubjectKeyIdentifier(byte[] subjectKeyID) {
+ throw new IllegalArgumentException();
+ }
- isSKIDSensitive = true;
- }
- }
+ /**
+ * This selector overrides the serialNumber matching rules of
+ * X509CertSelector, so it throws IllegalArgumentException if this method
+ * is ever called.
+ */
+ @Override
+ public void setSerialNumber(BigInteger serial) {
+ throw new IllegalArgumentException();
+ }
- SerialNumber asn = (SerialNumber)akidext.get(
- AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
+ /**
+ * Sets the subjectKeyIdentifier and serialNumber criteria from the
+ * authority key identifier extension.
+ *
+ * The subjectKeyIdentifier criterion is set to the keyIdentifier field
+ * of the extension, or null if it is empty. The serialNumber criterion
+ * is set to the authorityCertSerialNumber field, or null if it is empty.
+ *
+ * Note that we do not set the subject criterion to the
+ * authorityCertIssuer field of the extension. The caller MUST set
+ * the subject criterion before calling match().
+ *
+ * @param ext the authorityKeyIdentifier extension
+ * @throws IOException if there is an error parsing the extension
+ */
+ void setSkiAndSerialNumber(AuthorityKeyIdentifierExtension ext)
+ throws IOException {
+
+ ski = null;
+ serial = null;
+
+ if (ext != null) {
+ ski = ext.getEncodedKeyIdentifier();
+ SerialNumber asn = (SerialNumber)ext.get(
+ AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
if (asn != null) {
- // Do not override the previous setting for initial selection.
- if (isSNSensitive || getSerialNumber() == null) {
- super.setSerialNumber(asn.getNumber());
- isSNSensitive = true;
- }
+ serial = asn.getNumber();
}
-
- // the subject criterion should be set by the caller.
+ // the subject criterion should be set by the caller
}
}
/**
* Decides whether a <code>Certificate</code> should be selected.
*
+ * This method overrides the matching rules for the subjectKeyIdentifier
+ * and serialNumber criteria and adds additional rules for certificate
+ * validity.
+ *
* For the purpose of compatibility, when a certificate is of
* version 1 and version 2, or the certificate does not include
* a subject key identifier extension, the selection criterion
@@ -138,12 +153,28 @@
*/
@Override
public boolean match(Certificate cert) {
- if (!(cert instanceof X509Certificate)) {
+ X509Certificate xcert = (X509Certificate)cert;
+
+ // match subject key identifier
+ if (!matchSubjectKeyID(xcert)) {
return false;
}
- X509Certificate xcert = (X509Certificate)cert;
+ // In practice, a CA may replace its root certificate and require that
+ // the existing certificate is still valid, even if the AKID extension
+ // does not match the replacement root certificate fields.
+ //
+ // Conservatively, we only support the replacement for version 1 and
+ // version 2 certificate. As for version 3, the certificate extension
+ // may contain sensitive information (for example, policies), the
+ // AKID need to be respected to seek the exact certificate in case
+ // of key or certificate abuse.
int version = xcert.getVersion();
+ if (serial != null && version > 2) {
+ if (!serial.equals(xcert.getSerialNumber())) {
+ return false;
+ }
+ }
// Check the validity period for version 1 and 2 certificate.
if (version < 3) {
@@ -154,7 +185,6 @@
return false;
}
}
-
if (endDate != null) {
try {
xcert.checkValidity(endDate);
@@ -164,26 +194,53 @@
}
}
- // If no SubjectKeyIdentifier extension, don't bother to check it.
- if (isSKIDSensitive &&
- (version < 3 || xcert.getExtensionValue("2.5.29.14") == null)) {
- setSubjectKeyIdentifier(null);
+
+ if (!super.match(cert)) {
+ return false;
}
- // In practice, a CA may replace its root certificate and require that
- // the existing certificate is still valid, even if the AKID extension
- // does not match the replacement root certificate fields.
- //
- // Conservatively, we only support the replacement for version 1 and
- // version 2 certificate. As for version 2, the certificate extension
- // may contain sensitive information (for example, policies), the
- // AKID need to be respected to seek the exact certificate in case
- // of key or certificate abuse.
- if (isSNSensitive && version < 3) {
- setSerialNumber(null);
- }
+ return true;
+ }
- return super.match(cert);
+ /*
+ * Match on subject key identifier extension value. These matching rules
+ * are identical to X509CertSelector except that if the certificate does
+ * not have a subject key identifier extension, it returns true.
+ */
+ private boolean matchSubjectKeyID(X509Certificate xcert) {
+ if (ski == null) {
+ return true;
+ }
+ try {
+ byte[] extVal = xcert.getExtensionValue("2.5.29.14");
+ if (extVal == null) {
+ if (debug != null) {
+ debug.println("AdaptableX509CertSelector.match: "
+ + "no subject key ID extension. Subject: "
+ + xcert.getSubjectX500Principal());
+ }
+ return true;
+ }
+ DerInputStream in = new DerInputStream(extVal);
+ byte[] certSubjectKeyID = in.getOctetString();
+ if (certSubjectKeyID == null ||
+ !Arrays.equals(ski, certSubjectKeyID)) {
+ if (debug != null) {
+ debug.println("AdaptableX509CertSelector.match: "
+ + "subject key IDs don't match. "
+ + "Expected: " + Arrays.toString(ski) + " "
+ + "Cert's: " + Arrays.toString(certSubjectKeyID));
+ }
+ return false;
+ }
+ } catch (IOException ex) {
+ if (debug != null) {
+ debug.println("AdaptableX509CertSelector.match: "
+ + "exception in subject key ID check");
+ }
+ return false;
+ }
+ return true;
}
@Override
@@ -198,6 +255,9 @@
copy.endDate = (Date)endDate.clone();
}
+ if (ski != null) {
+ copy.ski = ski.clone();
+ }
return copy;
}
}
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java b/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java
index ab75ff0..e92590a 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,12 +31,10 @@
import java.util.Collections;
import java.util.Set;
import java.util.EnumSet;
-import java.util.HashSet;
import java.math.BigInteger;
import java.security.PublicKey;
import java.security.KeyFactory;
import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
import java.security.GeneralSecurityException;
import java.security.cert.Certificate;
import java.security.cert.X509CRL;
@@ -48,10 +46,13 @@
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.PKIXReason;
-import java.io.IOException;
-import java.security.interfaces.*;
-import java.security.spec.*;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPublicKeySpec;
+import sun.security.util.AnchorCertificates;
+import sun.security.util.CertConstraintParameters;
+import sun.security.util.Debug;
import sun.security.util.DisabledAlgorithmConstraints;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl;
@@ -69,18 +70,34 @@
* @see PKIXParameters
*/
final public class AlgorithmChecker extends PKIXCertPathChecker {
+ private static final Debug debug = Debug.getInstance("certpath");
private final AlgorithmConstraints constraints;
private final PublicKey trustedPubKey;
private PublicKey prevPubKey;
private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
- EnumSet.of(CryptoPrimitive.SIGNATURE);
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
+ private final static Set<CryptoPrimitive> KU_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(
+ CryptoPrimitive.SIGNATURE,
+ CryptoPrimitive.KEY_ENCAPSULATION,
+ CryptoPrimitive.PUBLIC_KEY_ENCRYPTION,
+ CryptoPrimitive.KEY_AGREEMENT));
private final static DisabledAlgorithmConstraints
certPathDefaultConstraints = new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
+ // If there is no "cacerts" keyword, then disable anchor checking
+ private static final boolean publicCALimits =
+ certPathDefaultConstraints.checkProperty("jdkCA");
+
+ // If anchor checking enabled, this will be true if the trust anchor
+ // has a match in the cacerts file
+ private boolean trustedMatch = false;
+
/**
* Create a new <code>AlgorithmChecker</code> with the algorithm
* constraints specified in security property
@@ -129,6 +146,11 @@
if (anchor.getTrustedCert() != null) {
this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+ // Check for anchor certificate restrictions
+ trustedMatch = checkFingerprint(anchor.getTrustedCert());
+ if (trustedMatch && debug != null) {
+ debug.println("trustedMatch = true");
+ }
} else {
this.trustedPubKey = anchor.getCAPublicKey();
}
@@ -137,6 +159,19 @@
this.constraints = constraints;
}
+ // Check this 'cert' for restrictions in the AnchorCertificates
+ // trusted certificates list
+ private static boolean checkFingerprint(X509Certificate cert) {
+ if (!publicCALimits) {
+ return false;
+ }
+
+ if (debug != null) {
+ debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
+ }
+ return AnchorCertificates.contains(cert);
+ }
+
@Override
public void init(boolean forward) throws CertPathValidatorException {
// Note that this class does not support forward mode.
@@ -174,45 +209,19 @@
return;
}
- X509CertImpl x509Cert = null;
- try {
- x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
- } catch (CertificateException ce) {
- throw new CertPathValidatorException(ce);
- }
-
- PublicKey currPubKey = x509Cert.getPublicKey();
- String currSigAlg = x509Cert.getSigAlgName();
-
- AlgorithmId algorithmId = null;
- try {
- algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
- } catch (CertificateException ce) {
- throw new CertPathValidatorException(ce);
- }
-
- AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
-
- // Check the current signature algorithm
- if (!constraints.permits(
- SIGNATURE_PRIMITIVE_SET,
- currSigAlg, currSigAlgParams)) {
- throw new CertPathValidatorException(
- "Algorithm constraints check failed: " + currSigAlg,
- null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
- }
-
// check the key usage and key size
- boolean[] keyUsage = x509Cert.getKeyUsage();
+ boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
if (keyUsage != null && keyUsage.length < 9) {
throw new CertPathValidatorException(
"incorrect KeyUsage extension",
null, null, -1, PKIXReason.INVALID_KEY_USAGE);
}
+ // Assume all key usage bits are set if key usage is not present
+ Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
+
if (keyUsage != null) {
- Set<CryptoPrimitive> primitives =
- EnumSet.noneOf(CryptoPrimitive.class);
+ primitives = EnumSet.noneOf(CryptoPrimitive.class);
if (keyUsage[0] || keyUsage[1] || keyUsage[5] || keyUsage[6]) {
// keyUsage[0]: KeyUsage.digitalSignature
@@ -237,26 +246,70 @@
// KeyUsage.encipherOnly and KeyUsage.decipherOnly are
// undefined in the absence of the keyAgreement bit.
- if (!primitives.isEmpty()) {
- if (!constraints.permits(primitives, currPubKey)) {
- throw new CertPathValidatorException(
- "algorithm constraints check failed",
- null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
- }
+ if (primitives.isEmpty()) {
+ throw new CertPathValidatorException(
+ "incorrect KeyUsage extension bits",
+ null, null, -1, PKIXReason.INVALID_KEY_USAGE);
}
}
+ PublicKey currPubKey = cert.getPublicKey();
+
+ // Check against DisabledAlgorithmConstraints certpath constraints.
+ // permits() will throw exception on failure.
+ certPathDefaultConstraints.permits(primitives,
+ new CertConstraintParameters((X509Certificate)cert,
+ trustedMatch));
+ // new CertConstraintParameters(x509Cert, trustedMatch));
+ // If there is no previous key, set one and exit
+ if (prevPubKey == null) {
+ prevPubKey = currPubKey;
+ return;
+ }
+
+ X509CertImpl x509Cert;
+ AlgorithmId algorithmId;
+ try {
+ x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+ algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+ } catch (CertificateException ce) {
+ throw new CertPathValidatorException(ce);
+ }
+
+ AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+ String currSigAlg = x509Cert.getSigAlgName();
+
+ // If 'constraints' is not of DisabledAlgorithmConstraints, check all
+ // everything individually
+ if (!(constraints instanceof DisabledAlgorithmConstraints)) {
+ // Check the current signature algorithm
+ if (!constraints.permits(
+ SIGNATURE_PRIMITIVE_SET,
+ currSigAlg, currSigAlgParams)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on signature " +
+ "algorithm: " + currSigAlg, null, null, -1,
+ BasicReason.ALGORITHM_CONSTRAINED);
+ }
+
+ if (!constraints.permits(primitives, currPubKey)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on keysize: " +
+ sun.security.util.KeyUtil.getKeySize(currPubKey),
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+ }
+ }
+
// Check with previous cert for signature algorithm and public key
if (prevPubKey != null) {
- if (currSigAlg != null) {
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException(
- "Algorithm constraints check failed: " + currSigAlg,
+ "Algorithm constraints check failed on " +
+ "signature algorithm: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
- }
// Inherit key parameters from previous key
if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
@@ -269,7 +322,7 @@
DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
if (params == null) {
throw new CertPathValidatorException(
- "Key parameters missing");
+ "Key parameters missing from public key.");
}
try {
@@ -317,6 +370,11 @@
// Don't bother to change the trustedPubKey.
if (anchor.getTrustedCert() != null) {
prevPubKey = anchor.getTrustedCert().getPublicKey();
+ // Check for anchor certificate restrictions
+ trustedMatch = checkFingerprint(anchor.getTrustedCert());
+ if (trustedMatch && debug != null) {
+ debug.println("trustedMatch = true");
+ }
} else {
prevPubKey = anchor.getCAPublicKey();
}
@@ -357,10 +415,10 @@
if (!certPathDefaultConstraints.permits(
SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
throw new CertPathValidatorException(
- "algorithm check failed: " + sigAlgName + " is disabled",
+ "Algorithm constraints check failed on signature algorithm: " +
+ sigAlgName + " is disabled",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
}
-
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/Builder.java b/ojluni/src/main/java/sun/security/provider/certpath/Builder.java
index e053b20..84cbe66 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/Builder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/Builder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -435,7 +435,12 @@
if (selector.match(targetCert) && !X509CertImpl.isSelfSigned
(targetCert, buildParams.sigProvider())) {
if (debug != null) {
- debug.println("Builder.addMatchingCerts: adding target cert");
+ debug.println("Builder.addMatchingCerts: " +
+ "adding target cert" +
+ "\n SN: " + Debug.toHexString(
+ targetCert.getSerialNumber()) +
+ "\n Subject: " + targetCert.getSubjectX500Principal() +
+ "\n Issuer: " + targetCert.getIssuerX500Principal());
}
return resultCerts.add(targetCert);
}
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java b/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java
index a08c990..28fb322 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -145,8 +145,8 @@
if (prevNC != null && ((i == certPathLength) ||
!X509CertImpl.isSelfIssued(currCert))) {
if (debug != null) {
- debug.println("prevNC = " + prevNC);
- debug.println("currDN = " + currCert.getSubjectX500Principal());
+ debug.println("prevNC = " + prevNC +
+ ", currDN = " + currCert.getSubjectX500Principal());
}
try {
@@ -184,8 +184,8 @@
currCertImpl.getNameConstraintsExtension();
if (debug != null) {
- debug.println("prevNC = " + prevNC);
- debug.println("newNC = " + String.valueOf(newConstraints));
+ debug.println("prevNC = " + prevNC +
+ ", newNC = " + String.valueOf(newConstraints));
}
// if there are no previous name constraints, we just return the
@@ -225,8 +225,8 @@
String msg = "basic constraints";
if (debug != null) {
debug.println("---checking " + msg + "...");
- debug.println("i = " + i);
- debug.println("maxPathLength = " + maxPathLength);
+ debug.println("i = " + i +
+ ", maxPathLength = " + maxPathLength);
}
/* check if intermediate cert */
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java b/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
index 34bfbba..5d9e657 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
@@ -33,7 +33,6 @@
import java.util.*;
import sun.security.util.Debug;
-import sun.security.util.DerOutputStream;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*;
@@ -320,6 +319,14 @@
Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
Date validity) throws CRLException, IOException {
+ if (debug != null) {
+ debug.println("DistributionPointFetcher.verifyCRL: " +
+ "checking revocation status for" +
+ "\n SN: " + Debug.toHexString(certImpl.getSerialNumber()) +
+ "\n Subject: " + certImpl.getSubjectX500Principal() +
+ "\n Issuer: " + certImpl.getIssuerX500Principal());
+ }
+
boolean indirectCRL = false;
X509CRLImpl crlImpl = X509CRLImpl.toImpl(crl);
IssuingDistributionPointExtension idpExt =
@@ -600,12 +607,9 @@
AuthorityKeyIdentifierExtension akidext =
crlImpl.getAuthKeyIdExtension();
if (akidext != null) {
- KeyIdentifier akid = (KeyIdentifier)akidext.get(
- AuthorityKeyIdentifierExtension.KEY_ID);
- if (akid != null) {
- DerOutputStream derout = new DerOutputStream();
- derout.putOctetString(akid.getIdentifier());
- certSel.setSubjectKeyIdentifier(derout.toByteArray());
+ byte[] kid = akidext.getEncodedKeyIdentifier();
+ if (kid != null) {
+ certSel.setSubjectKeyIdentifier(kid);
}
SerialNumber asn = (SerialNumber)akidext.get(
@@ -753,9 +757,7 @@
* issued. [section 5.2.1, RFC 2459]
*/
AuthorityKeyIdentifierExtension crlAKID = crl.getAuthKeyIdExtension();
- if (crlAKID != null) {
- issuerSelector.parseAuthorityKeyIdentifierExtension(crlAKID);
- }
+ issuerSelector.setSkiAndSerialNumber(crlAKID);
matched = issuerSelector.match(cert);
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java b/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
index 8f2a929..57e819c 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,9 +46,10 @@
import sun.security.util.Debug;
import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension;
+import sun.security.x509.AuthorityKeyIdentifierExtension;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.X500Name;
-import sun.security.x509.AuthorityKeyIdentifierExtension;
+import sun.security.x509.X509CertImpl;
/**
* This class represents a forward builder, which is able to retrieve
@@ -69,7 +70,6 @@
private AdaptableX509CertSelector caSelector;
private X509CertSelector caTargetSelector;
TrustAnchor trustAnchor;
- private Comparator<X509Certificate> comparator;
private boolean searchAllCertStores = true;
/**
@@ -93,7 +93,6 @@
trustedSubjectDNs.add(anchor.getCA());
}
}
- comparator = new PKIXCertComparator(trustedSubjectDNs);
this.searchAllCertStores = searchAllCertStores;
}
@@ -122,6 +121,8 @@
* As each cert is added, it is sorted based on the PKIXCertComparator
* algorithm.
*/
+ Comparator<X509Certificate> comparator =
+ new PKIXCertComparator(trustedSubjectDNs, currState.cert);
Set<X509Certificate> certs = new TreeSet<>(comparator);
/*
@@ -209,7 +210,8 @@
* getMatchingEECerts
*/
if (debug != null) {
- debug.println("ForwardBuilder.getMatchingCACerts(): ca is target");
+ debug.println("ForwardBuilder.getMatchingCACerts(): " +
+ "the target is a CA");
}
if (caTargetSelector == null) {
@@ -264,14 +266,6 @@
(caSelector, currentState.subjectNamesTraversed);
/*
- * Facilitate certification path construction with authority
- * key identifier and subject key identifier.
- */
- AuthorityKeyIdentifierExtension akidext =
- currentState.cert.getAuthorityKeyIdentifierExtension();
- caSelector.parseAuthorityKeyIdentifierExtension(akidext);
-
- /*
* check the validity period
*/
caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
@@ -291,8 +285,14 @@
for (X509Certificate trustedCert : trustedCerts) {
if (sel.match(trustedCert)) {
if (debug != null) {
- debug.println("ForwardBuilder.getMatchingCACerts: "
- + "found matching trust anchor");
+ debug.println("ForwardBuilder.getMatchingCACerts: " +
+ "found matching trust anchor." +
+ "\n SN: " +
+ Debug.toHexString(trustedCert.getSerialNumber()) +
+ "\n Subject: " +
+ trustedCert.getSubjectX500Principal() +
+ "\n Issuer: " +
+ trustedCert.getIssuerX500Principal());
}
if (caCerts.add(trustedCert) && !searchAllCertStores) {
return;
@@ -397,41 +397,68 @@
*
* Preference order for current cert:
*
- * 1) Issuer matches a trusted subject
+ * 1) The key identifier of an AKID extension (if present) in the
+ * previous certificate matches the key identifier in the SKID extension
+ *
+ * 2) Issuer matches a trusted subject
* Issuer: ou=D,ou=C,o=B,c=A
*
- * 2) Issuer is a descendant of a trusted subject (in order of
+ * 3) Issuer is a descendant of a trusted subject (in order of
* number of links to the trusted subject)
* a) Issuer: ou=E,ou=D,ou=C,o=B,c=A [links=1]
* b) Issuer: ou=F,ou=E,ou=D,ou=C,ou=B,c=A [links=2]
*
- * 3) Issuer is an ancestor of a trusted subject (in order of number of
+ * 4) Issuer is an ancestor of a trusted subject (in order of number of
* links to the trusted subject)
* a) Issuer: ou=C,o=B,c=A [links=1]
* b) Issuer: o=B,c=A [links=2]
*
- * 4) Issuer is in the same namespace as a trusted subject (in order of
+ * 5) Issuer is in the same namespace as a trusted subject (in order of
* number of links to the trusted subject)
* a) Issuer: ou=G,ou=C,o=B,c=A [links=2]
* b) Issuer: ou=H,o=B,c=A [links=3]
*
- * 5) Issuer is an ancestor of certificate subject (in order of number
+ * 6) Issuer is an ancestor of certificate subject (in order of number
* of links to the certificate subject)
* a) Issuer: ou=K,o=J,c=A
* Subject: ou=L,ou=K,o=J,c=A
* b) Issuer: o=J,c=A
* Subject: ou=L,ou=K,0=J,c=A
*
- * 6) Any other certificates
+ * 7) Any other certificates
*/
static class PKIXCertComparator implements Comparator<X509Certificate> {
- final static String METHOD_NME = "PKIXCertComparator.compare()";
+ static final String METHOD_NME = "PKIXCertComparator.compare()";
private final Set<X500Principal> trustedSubjectDNs;
+ private final X509CertSelector certSkidSelector;
- PKIXCertComparator(Set<X500Principal> trustedSubjectDNs) {
+ PKIXCertComparator(Set<X500Principal> trustedSubjectDNs,
+ X509CertImpl previousCert) throws IOException {
this.trustedSubjectDNs = trustedSubjectDNs;
+ this.certSkidSelector = getSelector(previousCert);
+ }
+
+ /**
+ * Returns an X509CertSelector for matching on the authority key
+ * identifier, or null if not applicable.
+ */
+ private X509CertSelector getSelector(X509CertImpl previousCert)
+ throws IOException {
+ if (previousCert != null) {
+ AuthorityKeyIdentifierExtension akidExt =
+ previousCert.getAuthorityKeyIdentifierExtension();
+ if (akidExt != null) {
+ byte[] skid = akidExt.getEncodedKeyIdentifier();
+ if (skid != null) {
+ X509CertSelector selector = new X509CertSelector();
+ selector.setSubjectKeyIdentifier(skid);
+ return selector;
+ }
+ }
+ }
+ return null;
}
/**
@@ -455,6 +482,16 @@
// if certs are the same, return 0
if (oCert1.equals(oCert2)) return 0;
+ // If akid/skid match then it is preferable
+ if (certSkidSelector != null) {
+ if (certSkidSelector.match(oCert1)) {
+ return -1;
+ }
+ if (certSkidSelector.match(oCert2)) {
+ return 1;
+ }
+ }
+
X500Principal cIssuer1 = oCert1.getIssuerX500Principal();
X500Principal cIssuer2 = oCert2.getIssuerX500Principal();
X500Name cIssuer1Name = X500Name.asX500Name(cIssuer1);
@@ -666,12 +703,11 @@
ForwardState currState = (ForwardState)currentState;
- /**
- * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
- * Android.
- // Don't bother to verify untrusted certificate more.
- currState.untrustedChecker.check(cert, Collections.<String>emptySet());
- * END Android-removed */
+ // BEGIN Android-removed: Certificate checking
+ // Android doesn't use this mechanism for checking untrusted certificates.
+ // // Don't bother to verify untrusted certificate more.
+ // currState.untrustedChecker.check(cert, Collections.<String>emptySet());
+ // END Android-removed: Certificate checking
/*
* check for looping - abort a loop if we encounter the same
@@ -776,6 +812,7 @@
* encountered.
*/
if (!currState.keyParamsNeeded()) {
+ // Android-changed: sigProvider is not required
if (buildParams.sigProvider() != null) {
(currState.cert).verify(cert.getPublicKey(),
buildParams.sigProvider());
@@ -836,6 +873,7 @@
* Check signature
*/
try {
+ // Android-changed: sigProvider is not required
if (buildParams.sigProvider() != null) {
cert.verify(publicKey, buildParams.sigProvider());
} else {
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java b/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java
index 09b9699..bdc437c 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java
@@ -75,11 +75,8 @@
/* the untrusted certificates checker */
- /**
- * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
- * Android.
- UntrustedChecker untrustedChecker;
- * END ANDROID_REMOVED */
+ // Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+ // UntrustedChecker untrustedChecker;
/* The list of user-defined checkers that support forward checking */
ArrayList<PKIXCertPathChecker> forwardCheckers;
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java b/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
index 550785e..492e851 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,7 +103,7 @@
*/
try {
X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
- selector.parseAuthorityKeyIdentifierExtension(
+ selector.setSkiAndSerialNumber(
firstCertImpl.getAuthorityKeyIdentifierExtension());
} catch (CertificateException | IOException e) {
// ignore
@@ -167,11 +167,8 @@
// create PKIXCertPathCheckers
List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
// add standard checkers that we will be using
- /**
- * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
- * Android.
- certPathCheckers.add(new UntrustedChecker());
- * END Android-removed */
+ // Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+ // certPathCheckers.add(new UntrustedChecker());
certPathCheckers.add(new AlgorithmChecker(anchor));
certPathCheckers.add(new KeyChecker(certPathLen,
params.targetCertConstraints()));
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java b/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
index db5edda..e85ef2d 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.StringJoiner;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXCertPathChecker;
@@ -88,20 +89,25 @@
* current certificate of this loop to be the previous certificate
* of the next loop. The state is initialized during first loop.
*/
- if (debug != null)
- debug.println("Checking cert" + (i+1) + " ...");
-
X509Certificate currCert = reversedCertList.get(i);
+
+ if (debug != null) {
+ debug.println("Checking cert" + (i+1) + " - Subject: " +
+ currCert.getSubjectX500Principal());
+ }
+
Set<String> unresCritExts = currCert.getCriticalExtensionOIDs();
if (unresCritExts == null) {
unresCritExts = Collections.<String>emptySet();
}
if (debug != null && !unresCritExts.isEmpty()) {
- debug.println("Set of critical extensions:");
+ StringJoiner joiner = new StringJoiner(", ", "{", "}");
for (String oid : unresCritExts) {
- debug.println(oid);
+ joiner.add(oid);
}
+ debug.println("Set of critical extensions: " +
+ joiner.toString());
}
for (int j = 0; j < certPathCheckers.size(); j++) {
@@ -125,8 +131,8 @@
} catch (CertPathValidatorException cpve) {
throw new CertPathValidatorException(cpve.getMessage(),
- cpve.getCause(), cpOriginal, cpSize - (i + 1),
- cpve.getReason());
+ (cpve.getCause() != null) ? cpve.getCause() : cpve,
+ cpOriginal, cpSize - (i + 1), cpve.getReason());
}
}
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java b/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java
index 78e8db6..1815a22 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java
@@ -356,13 +356,11 @@
return;
}
- /**
- * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
- * Android.
- // Don't bother to verify untrusted certificate more.
- currentState.untrustedChecker.check(cert,
- Collections.<String>emptySet());
- * END Android-removed */
+ // BEGIN Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+ // // Don't bother to verify untrusted certificate more.
+ // currentState.untrustedChecker.check(cert,
+ // Collections.<String>emptySet());
+ // END Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
/*
* check for looping - abort a loop if
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java b/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java
index 7ffd924..a9944af 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java
@@ -101,11 +101,8 @@
AlgorithmChecker algorithmChecker;
/* the untrusted certificates checker */
- /**
- * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
- * Android.
- UntrustedChecker untrustedChecker;
- * END Android-removed */
+ // Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+ // UntrustedChecker untrustedChecker;
/* the trust anchor used to validate the path */
TrustAnchor trustAnchor;
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java b/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
index 19b41f6..61d5fd7 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -343,11 +343,17 @@
PublicKey pubKey, boolean crlSignFlag)
throws CertPathValidatorException
{
+ if (debug != null) {
+ debug.println("RevocationChecker.check: checking cert" +
+ "\n SN: " + Debug.toHexString(xcert.getSerialNumber()) +
+ "\n Subject: " + xcert.getSubjectX500Principal() +
+ "\n Issuer: " + xcert.getIssuerX500Principal());
+ }
try {
if (onlyEE && xcert.getBasicConstraints() != -1) {
if (debug != null) {
- debug.println("Skipping revocation check, not end " +
- "entity cert");
+ debug.println("Skipping revocation check; cert is not " +
+ "an end entity cert");
}
return;
}
@@ -1035,6 +1041,9 @@
boolean signFlag = true;
List<? extends Certificate> cpList =
cpbr.getCertPath().getCertificates();
+ if (cpList.isEmpty()) {
+ return;
+ }
try {
for (int i = cpList.size()-1; i >= 0; i-- ) {
X509Certificate cert = (X509Certificate)cpList.get(i);
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java b/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java
index d2f8d23..9b21a99 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -136,7 +136,8 @@
PKIXCertPathBuilderResult result = buildCertPath(false, adjList);
if (result == null) {
if (debug != null) {
- debug.println("SunCertPathBuilder.engineBuild: 2nd pass");
+ debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " +
+ "try building again searching all certstores");
}
// try again
adjList.clear();
diff --git a/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java b/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java
index 4c3efd9..1b64d9d 100644
--- a/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java
+++ b/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
import java.security.AlgorithmConstraints;
import java.security.PrivilegedAction;
import java.security.Security;
-import java.util.Map;
import java.util.Set;
/**
@@ -45,8 +44,7 @@
}
// Get algorithm constraints from the specified security property.
- private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap,
- String propertyName) {
+ static String[] getAlgorithms(String propertyName) {
String property = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> Security.getProperty(
propertyName));
@@ -69,18 +67,7 @@
if (algorithmsInProperty == null) {
algorithmsInProperty = new String[0];
}
- algorithmsMap.put(propertyName, algorithmsInProperty);
- }
-
- static String[] getAlgorithms(Map<String, String[]> algorithmsMap,
- String propertyName) {
- synchronized (algorithmsMap) {
- if (!algorithmsMap.containsKey(propertyName)) {
- loadAlgorithmsMap(algorithmsMap, propertyName);
- }
-
- return algorithmsMap.get(propertyName);
- }
+ return algorithmsInProperty;
}
static boolean checkAlgorithm(String[] algorithms, String algorithm,
diff --git a/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java b/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java
index 394b846..dae529a 100644
--- a/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java
+++ b/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,19 +38,7 @@
private static final Pattern pattern =
Pattern.compile("with|and", Pattern.CASE_INSENSITIVE);
- /**
- * Decompose the standard algorithm name into sub-elements.
- * <p>
- * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
- * so that we can check the "SHA1" and "RSA" algorithm constraints
- * separately.
- * <p>
- * Please override the method if need to support more name pattern.
- */
- public Set<String> decompose(String algorithm) {
- if (algorithm == null || algorithm.length() == 0) {
- return new HashSet<>();
- }
+ private static Set<String> decomposeImpl(String algorithm) {
// algorithm/mode/padding
String[] transTockens = transPattern.split(algorithm);
@@ -76,6 +64,24 @@
elements.add(token);
}
}
+ return elements;
+ }
+
+ /**
+ * Decompose the standard algorithm name into sub-elements.
+ * <p>
+ * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
+ * so that we can check the "SHA1" and "RSA" algorithm constraints
+ * separately.
+ * <p>
+ * Please override the method if need to support more name pattern.
+ */
+ public Set<String> decompose(String algorithm) {
+ if (algorithm == null || algorithm.length() == 0) {
+ return new HashSet<>();
+ }
+
+ Set<String> elements = decomposeImpl(algorithm);
// In Java standard algorithm name specification, for different
// purpose, the SHA-1 and SHA-2 algorithm names are different. For
@@ -127,4 +133,40 @@
return elements;
}
+ private static void hasLoop(Set<String> elements, String find, String replace) {
+ if (elements.contains(find)) {
+ if (!elements.contains(replace)) {
+ elements.add(replace);
+}
+ elements.remove(find);
+ }
+ }
+
+ /*
+ * This decomposes a standard name into sub-elements with a consistent
+ * message digest algorithm name to avoid overly complicated checking.
+ */
+ public static Set<String> decomposeOneHash(String algorithm) {
+ if (algorithm == null || algorithm.length() == 0) {
+ return new HashSet<>();
+ }
+
+ Set<String> elements = decomposeImpl(algorithm);
+
+ hasLoop(elements, "SHA-1", "SHA1");
+ hasLoop(elements, "SHA-224", "SHA224");
+ hasLoop(elements, "SHA-256", "SHA256");
+ hasLoop(elements, "SHA-384", "SHA384");
+ hasLoop(elements, "SHA-512", "SHA512");
+
+ return elements;
+ }
+
+ /*
+ * The provided message digest algorithm name will return a consistent
+ * naming scheme.
+ */
+ public static String hashName(String algorithm) {
+ return algorithm.replace("-", "");
+ }
}
diff --git a/ojluni/src/main/java/sun/security/util/AnchorCertificates.java b/ojluni/src/main/java/sun/security/util/AnchorCertificates.java
new file mode 100644
index 0000000..6bc0030
--- /dev/null
+++ b/ojluni/src/main/java/sun/security/util/AnchorCertificates.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.AccessController;
+import java.security.KeyStore;
+import java.security.PrivilegedAction;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashSet;
+
+import sun.security.x509.X509CertImpl;
+
+/**
+ * The purpose of this class is to determine the trust anchor certificates is in
+ * the cacerts file. This is used for PKIX CertPath checking.
+ */
+public class AnchorCertificates {
+
+ private static final Debug debug = Debug.getInstance("certpath");
+ private static final String HASH = "SHA-256";
+ private static HashSet<String> certs;
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ File f = new File(System.getProperty("java.home"),
+ "lib/security/cacerts");
+ KeyStore cacerts;
+ try {
+ cacerts = KeyStore.getInstance("JKS");
+ try (FileInputStream fis = new FileInputStream(f)) {
+ cacerts.load(fis, "changeit".toCharArray());
+ certs = new HashSet<>();
+ Enumeration<String> list = cacerts.aliases();
+ String alias;
+ while (list.hasMoreElements()) {
+ alias = list.nextElement();
+ // Check if this cert is labeled a trust anchor.
+ if (alias.contains(" [jdk")) {
+ X509Certificate cert = (X509Certificate) cacerts
+ .getCertificate(alias);
+ certs.add(X509CertImpl.getFingerprint(HASH, cert));
+ }
+ }
+ }
+ } catch (Exception e) {
+ if (debug != null) {
+ debug.println("Error parsing cacerts");
+ }
+ e.printStackTrace();
+ }
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Checks if a certificate is a trust anchor.
+ *
+ * @param cert the certificate to check
+ * @return true if the certificate is trusted.
+ */
+ public static boolean contains(X509Certificate cert) {
+ String key = X509CertImpl.getFingerprint(HASH, cert);
+ boolean result = certs.contains(key);
+ if (result && debug != null) {
+ debug.println("AnchorCertificate.contains: matched " +
+ cert.getSubjectDN());
+ }
+ return result;
+ }
+
+ private AnchorCertificates() {}
+}
diff --git a/ojluni/src/main/java/sun/security/util/CertConstraintParameters.java b/ojluni/src/main/java/sun/security/util/CertConstraintParameters.java
new file mode 100644
index 0000000..9f7a938
--- /dev/null
+++ b/ojluni/src/main/java/sun/security/util/CertConstraintParameters.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * This class is a wrapper for keeping state and passing objects between PKIX,
+ * AlgorithmChecker, and DisabledAlgorithmConstraints.
+ */
+public class CertConstraintParameters {
+ // A certificate being passed to check against constraints.
+ private final X509Certificate cert;
+
+ // This is true if the trust anchor in the certificate chain matches a cert
+ // in AnchorCertificates
+ private final boolean trustedMatch;
+
+ public CertConstraintParameters(X509Certificate c, boolean match) {
+ cert = c;
+ trustedMatch = match;
+ }
+
+ public CertConstraintParameters(X509Certificate c) {
+ this(c, false);
+ }
+
+ // Returns if the trust anchor has a match if anchor checking is enabled.
+ public boolean isTrustedMatch() {
+ return trustedMatch;
+ }
+
+ public X509Certificate getCertificate() {
+ return cert;
+ }
+}
diff --git a/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java b/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java
index 05da9ba..d8c1462 100644
--- a/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java
+++ b/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,14 @@
import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters;
import java.security.Key;
-import java.util.Locale;
-import java.util.Set;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorException.BasicReason;
+import java.security.cert.X509Certificate;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
@@ -44,6 +46,7 @@
* for the syntax of the disabled algorithm string.
*/
public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
+ private static final Debug debug = Debug.getInstance("certpath");
// the known security property, jdk.certpath.disabledAlgorithms
public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
@@ -53,13 +56,9 @@
public final static String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms";
- private final static Map<String, String[]> disabledAlgorithmsMap =
- new HashMap<>();
- private final static Map<String, KeySizeConstraints> keySizeConstraintsMap =
- new HashMap<>();
private final String[] disabledAlgorithms;
- private final KeySizeConstraints keySizeConstraints;
+ private final Constraints algorithmConstraints;
/**
* Initialize algorithm constraints with the specified security property.
@@ -71,14 +70,25 @@
this(propertyName, new AlgorithmDecomposer());
}
+ /**
+ * Initialize algorithm constraints with the specified security property
+ * for a specific usage type.
+ *
+ * @param propertyName the security property name that define the disabled
+ * algorithm constraints
+ * @param decomposer an alternate AlgorithmDecomposer.
+ */
public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) {
super(decomposer);
- disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName);
- keySizeConstraints = getKeySizeConstraints(disabledAlgorithms,
- propertyName);
+ disabledAlgorithms = getAlgorithms(propertyName);
+ algorithmConstraints = new Constraints(disabledAlgorithms);
}
+ /*
+ * This only checks if the algorithm has been completely disabled. If
+ * there are keysize or other limit, this method allow the algorithm.
+ */
@Override
final public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) {
@@ -90,11 +100,19 @@
return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
}
+ /*
+ * Checks if the key algorithm has been disabled or constraints have been
+ * placed on the key.
+ */
@Override
final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
return checkConstraints(primitives, "", key, null);
}
+ /*
+ * Checks if the key algorithm has been disabled or if constraints have
+ * been placed on the key.
+ */
@Override
final public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) {
@@ -106,7 +124,39 @@
return checkConstraints(primitives, algorithm, key, parameters);
}
- // Check algorithm constraints
+ /*
+ * Check if a x509Certificate object is permitted. Check if all
+ * algorithms are allowed, certificate constraints, and the
+ * public key against key constraints.
+ *
+ * Uses new style permit() which throws exceptions.
+ */
+ public final void permits(Set<CryptoPrimitive> primitives,
+ CertConstraintParameters cp) throws CertPathValidatorException {
+ checkConstraints(primitives, cp);
+ }
+
+ /*
+ * Check if Certificate object is within the constraints.
+ * Uses new style permit() which throws exceptions.
+ */
+ public final void permits(Set<CryptoPrimitive> primitives,
+ X509Certificate cert) throws CertPathValidatorException {
+ checkConstraints(primitives, new CertConstraintParameters(cert));
+ }
+
+ // Check if a string is contained inside the property
+ public boolean checkProperty(String param) {
+ param = param.toLowerCase(Locale.ENGLISH);
+ for (String block : disabledAlgorithms) {
+ if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Check algorithm constraints with key and algorithm
private boolean checkConstraints(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) {
@@ -115,7 +165,7 @@
throw new IllegalArgumentException("The key cannot be null");
}
- // check the target algorithm
+ // check the signature algorithm
if (algorithm != null && algorithm.length() != 0) {
if (!permits(primitives, algorithm, parameters)) {
return false;
@@ -128,97 +178,203 @@
}
// check the key constraints
- if (keySizeConstraints.disables(key)) {
- return false;
- }
-
- return true;
+ return algorithmConstraints.permits(key);
}
- private static KeySizeConstraints getKeySizeConstraints(
- String[] disabledAlgorithms, String propertyName) {
- synchronized (keySizeConstraintsMap) {
- if(!keySizeConstraintsMap.containsKey(propertyName)) {
- // map the key constraints
- KeySizeConstraints keySizeConstraints =
- new KeySizeConstraints(disabledAlgorithms);
- keySizeConstraintsMap.put(propertyName, keySizeConstraints);
- }
+ /*
+ * Check algorithm constraints with Certificate
+ * Uses new style permit() which throws exceptions.
+ */
+ private void checkConstraints(Set<CryptoPrimitive> primitives,
+ CertConstraintParameters cp) throws CertPathValidatorException {
- return keySizeConstraintsMap.get(propertyName);
+ X509Certificate cert = cp.getCertificate();
+ String algorithm = cert.getSigAlgName();
+
+ // Check signature algorithm is not disabled
+ if (!permits(primitives, algorithm, null)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on disabled "+
+ "signature algorithm: " + algorithm,
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
+
+ // Check key algorithm is not disabled
+ if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on disabled "+
+ "public key algorithm: " + algorithm,
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+ }
+
+ // Check the certificate and key constraints
+ algorithmConstraints.permits(cp);
+
}
/**
- * key constraints
+ * Key and Certificate Constraints
+ *
+ * The complete disabling of an algorithm is not handled by Constraints or
+ * Constraint classes. That is addressed with
+ * permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
+ *
+ * When passing a Key to permit(), the boolean return values follow the
+ * same as the interface class AlgorithmConstraints.permit(). This is to
+ * maintain compatibility:
+ * 'true' means the operation is allowed.
+ * 'false' means it failed the constraints and is disallowed.
+ *
+ * When passing CertConstraintParameters through permit(), an exception
+ * will be thrown on a failure to better identify why the operation was
+ * disallowed.
*/
- private static class KeySizeConstraints {
- private static final Pattern pattern = Pattern.compile(
- "(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
- private Map<String, Set<KeySizeConstraint>> constraintsMap =
- Collections.synchronizedMap(
- new HashMap<String, Set<KeySizeConstraint>>());
+ private static class Constraints {
+ private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
+ private static final Pattern keySizePattern = Pattern.compile(
+ "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
- public KeySizeConstraints(String[] restrictions) {
- for (String restriction : restrictions) {
- if (restriction == null || restriction.isEmpty()) {
+ public Constraints(String[] constraintArray) {
+ for (String constraintEntry : constraintArray) {
+ if (constraintEntry == null || constraintEntry.isEmpty()) {
continue;
}
- Matcher matcher = pattern.matcher(restriction);
- if (matcher.matches()) {
- String algorithm = matcher.group(1);
+ constraintEntry = constraintEntry.trim();
+ if (debug != null) {
+ debug.println("Constraints: " + constraintEntry);
+ }
- KeySizeConstraint.Operator operator =
- KeySizeConstraint.Operator.of(matcher.group(2));
- int length = Integer.parseInt(matcher.group(3));
+ // Check if constraint is a complete disabling of an
+ // algorithm or has conditions.
+ String algorithm;
+ String policy;
+ int space = constraintEntry.indexOf(' ');
+ if (space > 0) {
+ algorithm = AlgorithmDecomposer.hashName(
+ constraintEntry.substring(0, space).
+ toUpperCase(Locale.ENGLISH));
+ policy = constraintEntry.substring(space + 1);
+ } else {
+ constraintsMap.computeIfAbsent(
+ constraintEntry.toUpperCase(Locale.ENGLISH),
+ k -> new HashSet<>());
+ continue;
+ }
- algorithm = algorithm.toLowerCase(Locale.ENGLISH);
+ // Convert constraint conditions into Constraint classes
+ Constraint c, lastConstraint = null;
+ // Allow only one jdkCA entry per constraint entry
+ boolean jdkCALimit = false;
- synchronized (constraintsMap) {
- if (!constraintsMap.containsKey(algorithm)) {
- constraintsMap.put(algorithm,
- new HashSet<KeySizeConstraint>());
+ for (String entry : policy.split("&")) {
+ entry = entry.trim();
+
+ Matcher matcher = keySizePattern.matcher(entry);
+ if (matcher.matches()) {
+ if (debug != null) {
+ debug.println("Constraints set to keySize: " +
+ entry);
}
+ c = new KeySizeConstraint(algorithm,
+ KeySizeConstraint.Operator.of(matcher.group(1)),
+ Integer.parseInt(matcher.group(2)));
- Set<KeySizeConstraint> constraintSet =
- constraintsMap.get(algorithm);
- KeySizeConstraint constraint =
- new KeySizeConstraint(operator, length);
- constraintSet.add(constraint);
+ } else if (entry.equalsIgnoreCase("jdkCA")) {
+ if (debug != null) {
+ debug.println("Constraints set to jdkCA.");
+ }
+ if (jdkCALimit) {
+ throw new IllegalArgumentException("Only one " +
+ "jdkCA entry allowed in property. " +
+ "Constraint: " + constraintEntry);
+ }
+ c = new jdkCAConstraint(algorithm);
+ jdkCALimit = true;
+ } else {
+ throw new IllegalArgumentException("Error in security" +
+ " property. Constraint unknown: " + entry);
}
+
+ // Link multiple conditions for a single constraint
+ // into a linked list.
+ if (lastConstraint == null) {
+ if (!constraintsMap.containsKey(algorithm)) {
+ constraintsMap.putIfAbsent(algorithm,
+ new HashSet<>());
+ }
+ constraintsMap.get(algorithm).add(c);
+ } else {
+ lastConstraint.nextConstraint = c;
+ }
+ lastConstraint = c;
}
}
}
- // Does this KeySizeConstraints disable the specified key?
- public boolean disables(Key key) {
- String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH);
- synchronized (constraintsMap) {
- if (constraintsMap.containsKey(algorithm)) {
- Set<KeySizeConstraint> constraintSet =
- constraintsMap.get(algorithm);
- for (KeySizeConstraint constraint : constraintSet) {
- if (constraint.disables(key)) {
- return true;
- }
- }
- }
- }
+ // Get applicable constraints based off the signature algorithm
+ private Set<Constraint> getConstraints(String algorithm) {
+ return constraintsMap.get(algorithm);
+ }
+ // Check if KeySizeConstraints permit the specified key
+ public boolean permits(Key key) {
+ Set<Constraint> set = getConstraints(key.getAlgorithm());
+ if (set == null) {
+ return true;
+ }
+ for (Constraint constraint : set) {
+ if (!constraint.permits(key)) {
+ if (debug != null) {
+ debug.println("keySizeConstraint: failed key " +
+ "constraint check " + KeyUtil.getKeySize(key));
+ }
return false;
}
+ }
+ return true;
}
- /**
- * Key size constraint.
- *
- * e.g. "keysize <= 1024"
- */
- private static class KeySizeConstraint {
+ // Check if constraints permit this cert.
+ public void permits(CertConstraintParameters cp)
+ throws CertPathValidatorException {
+ X509Certificate cert = cp.getCertificate();
+
+ if (debug != null) {
+ debug.println("Constraints.permits(): " + cert.getSigAlgName());
+ }
+
+ // Get all signature algorithms to check for constraints
+ Set<String> algorithms =
+ AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
+ if (algorithms == null || algorithms.isEmpty()) {
+ return;
+ }
+
+ // Attempt to add the public key algorithm to the set
+ algorithms.add(cert.getPublicKey().getAlgorithm());
+
+ // Check all applicable constraints
+ for (String algorithm : algorithms) {
+ Set<Constraint> set = getConstraints(algorithm);
+ if (set == null) {
+ continue;
+ }
+ for (Constraint constraint : set) {
+ constraint.permits(cp);
+ }
+ }
+ }
+ }
+
+ // Abstract class for algorithm constraint checking
+ private abstract static class Constraint {
+ String algorithm;
+ Constraint nextConstraint = null;
+
// operator
- static enum Operator {
+ enum Operator {
EQ, // "=="
NE, // "!="
LT, // "<"
@@ -242,16 +398,77 @@
return GE;
}
- throw new IllegalArgumentException(
- s + " is not a legal Operator");
+ throw new IllegalArgumentException("Error in security " +
+ "property. " + s + " is not a legal Operator");
}
}
+ /**
+ * Check if an algorithm constraint permit this key to be used.
+ * @param key Public key
+ * @return true if constraints do not match
+ */
+ public boolean permits(Key key) {
+ return true;
+ }
+
+ /**
+ * Check if an algorithm constraint is permit this certificate to
+ * be used.
+ * @param cp CertificateParameter containing certificate and state info
+ * @return true if constraints do not match
+ */
+ public abstract void permits(CertConstraintParameters cp)
+ throws CertPathValidatorException;
+ }
+
+ /*
+ * This class contains constraints dealing with the certificate chain
+ * of the certificate.
+ */
+ private static class jdkCAConstraint extends Constraint {
+ jdkCAConstraint(String algo) {
+ algorithm = algo;
+ }
+
+ /*
+ * Check if each constraint fails and check if there is a linked
+ * constraint Any permitted constraint will exit the linked list
+ * to allow the operation.
+ */
+ public void permits(CertConstraintParameters cp)
+ throws CertPathValidatorException {
+ if (debug != null) {
+ debug.println("jdkCAConstraints.permits(): " + algorithm);
+ }
+
+ // Return false if the chain has a trust anchor in cacerts
+ if (cp.isTrustedMatch()) {
+ if (nextConstraint != null) {
+ nextConstraint.permits(cp);
+ return;
+ }
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on certificate " +
+ "anchor limits",
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+ }
+ }
+ }
+
+
+ /*
+ * This class contains constraints dealing with the key size
+ * support limits per algorithm. e.g. "keySize <= 1024"
+ */
+ private static class KeySizeConstraint extends Constraint {
+
private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes
- public KeySizeConstraint(Operator operator, int length) {
+ public KeySizeConstraint(String algo, Operator operator, int length) {
+ algorithm = algo;
switch (operator) {
case EQ: // an unavailable key size
this.minSize = 0;
@@ -285,21 +502,58 @@
}
}
- // Does this key constraint disable the specified key?
- public boolean disables(Key key) {
- int size = KeyUtil.getKeySize(key);
+ /*
+ * If we are passed a certificate, extract the public key and use it.
+ *
+ * Check if each constraint fails and check if there is a linked
+ * constraint Any permitted constraint will exit the linked list
+ * to allow the operation.
+ */
+ public void permits(CertConstraintParameters cp)
+ throws CertPathValidatorException {
+ if (!permitsImpl(cp.getCertificate().getPublicKey())) {
+ if (nextConstraint != null) {
+ nextConstraint.permits(cp);
+ return;
+ }
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on keysize limits",
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+ }
+ }
+
+ // Check if key constraint disable the specified key
+ // Uses old style permit()
+ public boolean permits(Key key) {
+ // If we recursively find a constraint that permits us to use
+ // this key, return true and skip any other constraint checks.
+ if (nextConstraint != null && nextConstraint.permits(key)) {
+ return true;
+ }
+ if (debug != null) {
+ debug.println("KeySizeConstraints.permits(): " + algorithm);
+ }
+
+ return permitsImpl(key);
+ }
+
+ private boolean permitsImpl(Key key) {
+ // Verify this constraint is for this public key algorithm
+ if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
+ return true;
+ }
+
+ int size = KeyUtil.getKeySize(key);
if (size == 0) {
- return true; // we don't allow any key of size 0.
+ return false; // we don't allow any key of size 0.
} else if (size > 0) {
- return ((size < minSize) || (size > maxSize) ||
+ return !((size < minSize) || (size > maxSize) ||
(prohibitedSize == size));
} // Otherwise, the key size is not accessible. Conservatively,
// please don't disable such keys.
- return false;
+ return true;
+ }
}
}
-
-}
-
diff --git a/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java b/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java
index afd7c99..9e76a3a 100644
--- a/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java
+++ b/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java
@@ -307,4 +307,16 @@
public String getName() {
return (NAME);
}
+
+ /**
+ * Return the encoded key identifier, or null if not specified.
+ */
+ public byte[] getEncodedKeyIdentifier() throws IOException {
+ if (id != null) {
+ DerOutputStream derOut = new DerOutputStream();
+ id.encode(derOut);
+ return derOut.toByteArray();
+ }
+ return null;
+ }
}
diff --git a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
index f9db2c5..de4d313 100644
--- a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
+++ b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
@@ -1970,7 +1970,7 @@
// BEGIN Android-removed
// public String getFingerprint(String algorithm) {
// return fingerprints.computeIfAbsent(algorithm,
-// x -> getCertificateFingerPrint(x));
+// x -> getFingerprint(x, this));
// }
// END Android-removed
@@ -1978,11 +1978,12 @@
* Gets the requested finger print of the certificate. The result
* only contains 0-9 and A-F. No small case, no colon.
*/
- private String getCertificateFingerPrint(String mdAlg) {
+ public static String getFingerprint(String algorithm,
+ X509Certificate cert) {
String fingerPrint = "";
try {
- byte[] encCertInfo = getEncoded();
- MessageDigest md = MessageDigest.getInstance(mdAlg);
+ byte[] encCertInfo = cert.getEncoded();
+ MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] digest = md.digest(encCertInfo);
StringBuffer buf = new StringBuffer();
for (int i = 0; i < digest.length; i++) {
diff --git a/ojluni/src/main/native/PlainSocketImpl.c b/ojluni/src/main/native/PlainSocketImpl.c
index e2ba1dc..c4b5be7 100644
--- a/ojluni/src/main/native/PlainSocketImpl.c
+++ b/ojluni/src/main/native/PlainSocketImpl.c
@@ -90,33 +90,6 @@
}
/*
- * Create the marker file descriptor by establishing a loopback connection
- * which we shutdown but do not close the fd. The result is an fd that
- * can be used for read/write.
- */
-static int getMarkerFD()
-{
- int sv[2];
-
-#ifdef AF_UNIX
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
- return -1;
- }
-#else
- return -1;
-#endif
-
- /*
- * Finally shutdown sv[0] (any reads to this fd will get
- * EOF; any writes will get an error).
- */
- JVM_SocketShutdown(sv[0], 2);
- JVM_SocketClose(sv[1]);
-
- return sv[0];
-}
-
-/*
* Return the file descriptor given a PlainSocketImpl
*/
static int getFD(JNIEnv *env, jobject this) {
@@ -162,724 +135,6 @@
/*
* Class: java_net_PlainSocketImpl
- * Method: socketCreate
- * Signature: (Z)V */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
- jboolean stream) {
- jobject fdObj, ssObj;
- int fd;
- int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
-#ifdef AF_INET6
- int domain = ipv6_available() ? AF_INET6 : AF_INET;
-#else
- int domain = AF_INET;
-#endif
-
- if (socketExceptionCls == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/SocketException");
- CHECK_NULL(c);
- socketExceptionCls = (jclass)(*env)->NewGlobalRef(env, c);
- CHECK_NULL(socketExceptionCls);
- }
- fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
- if (fdObj == NULL) {
- (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
- return;
- }
-
- if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) {
- /* note: if you run out of fds, you may not be able to load
- * the exception class, and get a NoClassDefFoundError
- * instead.
- */
- NET_ThrowNew(env, errno, "can't create socket");
- return;
- }
- tagSocket(env, fd);
-
-#ifdef AF_INET6
- /* Disable IPV6_V6ONLY to ensure dual-socket support */
- if (domain == AF_INET6) {
- int arg = 0;
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
- sizeof(int)) < 0) {
- NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
- untagSocket(env, fd);
- close(fd);
- return;
- }
- }
-#endif /* AF_INET6 */
-
- /*
- * If this is a server socket then enable SO_REUSEADDR
- * automatically and set to non blocking.
- */
- ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
- if (ssObj != NULL) {
- int arg = 1;
- SET_NONBLOCKING(fd);
- if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
- sizeof(arg)) < 0) {
- NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
- untagSocket(env, fd);
- close(fd);
- return;
- }
- }
-
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
-}
-
-/*
- * inetAddress is the address object passed to the socket connect
- * call.
- *
- * Class: java_net_PlainSocketImpl
- * Method: socketConnect
- * Signature: (Ljava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
- jobject iaObj, jint port,
- jint timeout)
-{
- jint localport = (*env)->GetIntField(env, this, psi_localportID);
- int len = 0;
-
- /* fdObj is the FileDescriptor field on this */
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
- jclass clazz = (*env)->GetObjectClass(env, this);
-
- jobject fdLock;
-
- jint trafficClass = (*env)->GetIntField(env, this, psi_trafficClassID);
-
- /* fd is an int field on iaObj */
- jint fd;
-
- SOCKADDR him;
- /* The result of the connection */
- int connect_rv = -1;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
- return;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
- if (IS_NULL(iaObj)) {
- JNU_ThrowNullPointerException(env, "inet address argument null.");
- return;
- }
-
- /* connect */
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&him, &len, JNI_TRUE) != 0) {
- return;
- }
- setDefaultScopeID(env, (struct sockaddr *)&him);
-
-#ifdef AF_INET6
- if (trafficClass != 0 && ipv6_available()) {
- NET_SetTrafficClass((struct sockaddr *)&him, trafficClass);
- }
-#endif /* AF_INET6 */
- if (timeout <= 0) {
- connect_rv = NET_Connect(fd, (struct sockaddr *)&him, len);
-#ifdef __solaris__
- if (connect_rv == JVM_IO_ERR && errno == EINPROGRESS ) {
-
- /* This can happen if a blocking connect is interrupted by a signal.
- * See 6343810.
- */
- while (1) {
-#ifndef USE_SELECT
- {
- struct pollfd pfd;
- pfd.fd = fd;
- pfd.events = POLLOUT;
-
- connect_rv = NET_Poll(&pfd, 1, -1);
- }
-#else
- {
- fd_set wr, ex;
-
- FD_ZERO(&wr);
- FD_SET(fd, &wr);
- FD_ZERO(&ex);
- FD_SET(fd, &ex);
-
- connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
- }
-#endif
-
- if (connect_rv == JVM_IO_ERR) {
- if (errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- if (connect_rv > 0) {
- int optlen;
- /* has connection been established */
- optlen = sizeof(connect_rv);
- if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
- (void*)&connect_rv, &optlen) <0) {
- connect_rv = errno;
- }
-
- if (connect_rv != 0) {
- /* restore errno */
- errno = connect_rv;
- connect_rv = JVM_IO_ERR;
- }
- break;
- }
- }
- }
-#endif
- } else {
- /*
- * A timeout was specified. We put the socket into non-blocking
- * mode, connect, and then wait for the connection to be
- * established, fail, or timeout.
- */
- SET_NONBLOCKING(fd);
-
- /* no need to use NET_Connect as non-blocking */
- connect_rv = connect(fd, (struct sockaddr *)&him, len);
-
- /* connection not established immediately */
- if (connect_rv != 0) {
- int optlen;
- jlong prevTime = JVM_CurrentTimeMillis(env, 0);
-
- if (errno != EINPROGRESS) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
- "connect failed");
- SET_BLOCKING(fd);
- return;
- }
-
- /*
- * Wait for the connection to be established or a
- * timeout occurs. poll/select needs to handle EINTR in
- * case lwp sig handler redirects any process signals to
- * this thread.
- */
- while (1) {
- jlong newTime;
-#ifndef USE_SELECT
- {
- struct pollfd pfd;
- pfd.fd = fd;
- pfd.events = POLLOUT;
-
- errno = 0;
- connect_rv = NET_Poll(&pfd, 1, timeout);
- }
-#else
- {
- fd_set wr, ex;
- struct timeval t;
-
- t.tv_sec = timeout / 1000;
- t.tv_usec = (timeout % 1000) * 1000;
-
- FD_ZERO(&wr);
- FD_SET(fd, &wr);
- FD_ZERO(&ex);
- FD_SET(fd, &ex);
-
- errno = 0;
- connect_rv = NET_Select(fd+1, 0, &wr, &ex, &t);
- }
-#endif
-
- if (connect_rv >= 0) {
- break;
- }
- if (errno != EINTR) {
- break;
- }
-
- /*
- * The poll was interrupted so adjust timeout and
- * restart
- */
- newTime = JVM_CurrentTimeMillis(env, 0);
- timeout -= (newTime - prevTime);
- if (timeout <= 0) {
- connect_rv = 0;
- break;
- }
- prevTime = newTime;
-
- } /* while */
-
- if (connect_rv == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
- "connect timed out");
-
- /*
- * Timeout out but connection may still be established.
- * At the high level it should be closed immediately but
- * just in case we make the socket blocking again and
- * shutdown input & output.
- */
- SET_BLOCKING(fd);
- JVM_SocketShutdown(fd, 2);
- return;
- }
-
- /* has connection been established */
- optlen = sizeof(connect_rv);
- if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
- &optlen) <0) {
- connect_rv = errno;
- }
- }
-
- /* make socket blocking again */
- SET_BLOCKING(fd);
-
- /* restore errno */
- if (connect_rv != 0) {
- errno = connect_rv;
- connect_rv = JVM_IO_ERR;
- }
- }
-
- /* report the appropriate exception */
- if (connect_rv < 0) {
-
-#ifdef __linux__
- /*
- * Linux/GNU distribution setup /etc/hosts so that
- * InetAddress.getLocalHost gets back the loopback address
- * rather than the host address. Thus a socket can be
- * bound to the loopback address and the connect will
- * fail with EADDRNOTAVAIL. In addition the Linux kernel
- * returns the wrong error in this case - it returns EINVAL
- * instead of EADDRNOTAVAIL. We handle this here so that
- * a more descriptive exception text is used.
- */
- if (connect_rv == JVM_IO_ERR && errno == EINVAL) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Invalid argument or cannot assign requested address");
- return;
- }
-#endif
- if (connect_rv == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
- "operation interrupted");
-#if defined(EPROTO)
- } else if (errno == EPROTO) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ProtocolException",
- "Protocol error");
-#endif
- } else if (errno == ECONNREFUSED) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
- "Connection refused");
- } else if (errno == ETIMEDOUT) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
- "Connection timed out");
- } else if (errno == EHOSTUNREACH) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
- "Host unreachable");
- } else if (errno == EADDRNOTAVAIL) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
- "Address not available");
- } else if ((errno == EISCONN) || (errno == EBADF)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Socket closed");
- } else {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "connect failed");
- }
- return;
- }
-
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
-
- /* set the remote peer address and port */
- (*env)->SetObjectField(env, this, psi_addressID, iaObj);
- (*env)->SetIntField(env, this, psi_portID, port);
-
- /*
- * we need to initialize the local port field if bind was called
- * previously to the connect (by the client) then localport field
- * will already be initialized
- */
- if (localport == 0) {
- /* Now that we're a connected socket, let's extract the port number
- * that the system chose for us and store it in the Socket object.
- */
- len = SOCKADDR_LEN;
- if (JVM_GetSockName(fd, (struct sockaddr *)&him, &len) == -1) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "Error getting socket name");
- } else {
- localport = NET_GetPortFromSockaddr((struct sockaddr *)&him);
- (*env)->SetIntField(env, this, psi_localportID, localport);
- }
- }
-}
-
-/*
- * Class: java_net_PlainSocketImpl
- * Method: socketBind
- * Signature: (Ljava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketBind(JNIEnv *env, jobject this,
- jobject iaObj, jint localport) {
-
- /* fdObj is the FileDescriptor field on this */
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- /* fd is an int field on fdObj */
- int fd;
- int len;
- SOCKADDR him;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Socket closed");
- return;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
- if (IS_NULL(iaObj)) {
- JNU_ThrowNullPointerException(env, "iaObj is null.");
- return;
- }
-
- /* bind */
- if (NET_InetAddressToSockaddr(env, iaObj, localport, (struct sockaddr *)&him, &len, JNI_TRUE) != 0) {
- return;
- }
- setDefaultScopeID(env, (struct sockaddr *)&him);
-
- if (NET_Bind(fd, (struct sockaddr *)&him, len) < 0) {
- if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
- errno == EPERM || errno == EACCES) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "BindException",
- "Bind failed");
- } else {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "Bind failed");
- }
- return;
- }
-
- /* set the address */
- (*env)->SetObjectField(env, this, psi_addressID, iaObj);
-
- /* initialize the local port */
- if (localport == 0) {
- /* Now that we're a connected socket, let's extract the port number
- * that the system chose for us and store it in the Socket object.
- */
- if (JVM_GetSockName(fd, (struct sockaddr *)&him, &len) == -1) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "Error getting socket name");
- return;
- }
- localport = NET_GetPortFromSockaddr((struct sockaddr *)&him);
- (*env)->SetIntField(env, this, psi_localportID, localport);
- } else {
- (*env)->SetIntField(env, this, psi_localportID, localport);
- }
-}
-
-/*
- * Class: java_net_PlainSocketImpl
- * Method: socketListen
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketListen (JNIEnv *env, jobject this,
- jint count)
-{
- /* this FileDescriptor fd field */
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- /* fdObj's int fd field */
- int fd;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Socket closed");
- return;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
-
- /*
- * Workaround for bugid 4101691 in Solaris 2.6. See 4106600.
- * If listen backlog is Integer.MAX_VALUE then subtract 1.
- */
- if (count == 0x7fffffff)
- count -= 1;
-
- if (JVM_Listen(fd, count) == JVM_IO_ERR) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "Listen failed");
- }
-}
-
-/*
- * Class: java_net_PlainSocketImpl
- * Method: socketAccept
- * Signature: (Ljava/net/SocketImpl;)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
- jobject socket)
-{
- /* fields on this */
- int port;
- jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
- jlong prevTime = 0;
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
- /* the FileDescriptor field on socket */
- jobject socketFdObj;
- /* the InetAddress field on socket */
- jobject socketAddressObj;
-
- /* the ServerSocket fd int field on fdObj */
- jint fd;
-
- /* accepted fd */
- jint newfd;
-
- SOCKADDR him;
- int len;
-
- len = SOCKADDR_LEN;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Socket closed");
- return;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
- if (IS_NULL(socket)) {
- JNU_ThrowNullPointerException(env, "socket is null");
- return;
- }
-
- /*
- * accept connection but ignore ECONNABORTED indicating that
- * connection was eagerly accepted by the OS but was reset
- * before accept() was called.
- *
- * If accept timeout in place and timeout is adjusted with
- * each ECONNABORTED or EWOULDBLOCK to ensure that semantics
- * of timeout are preserved.
- */
- for (;;) {
- int ret;
-
- /* first usage pick up current time */
- if (prevTime == 0 && timeout > 0) {
- prevTime = JVM_CurrentTimeMillis(env, 0);
- }
-
- /* passing a timeout of 0 to poll will return immediately,
- but in the case of ServerSocket 0 means infinite. */
- if (timeout <= 0) {
- ret = NET_Timeout(fd, -1);
- } else {
- ret = NET_Timeout(fd, timeout);
- }
-
- if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
- "Accept timed out");
- return;
- } else if (ret == JVM_IO_ERR) {
- if (errno == EBADF) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
- } else {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Accept failed");
- }
- return;
- } else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
- "operation interrupted");
- return;
- }
-
- newfd = NET_Accept(fd, (struct sockaddr *)&him, (jint*)&len);
-
- /* connection accepted */
- if (newfd >= 0) {
- SET_BLOCKING(newfd);
- break;
- }
-
- /* non (ECONNABORTED or EWOULDBLOCK) error */
- if (!(errno == ECONNABORTED || errno == EWOULDBLOCK)) {
- break;
- }
-
- /* ECONNABORTED or EWOULDBLOCK error so adjust timeout if there is one. */
- if (timeout) {
- jlong currTime = JVM_CurrentTimeMillis(env, 0);
- timeout -= (currTime - prevTime);
-
- if (timeout <= 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
- "Accept timed out");
- return;
- }
- prevTime = currTime;
- }
- }
-
- if (newfd < 0) {
- if (newfd == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
- "operation interrupted");
- } else {
- if (errno == EINVAL) {
- errno = EBADF;
- }
- if (errno == EBADF) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
- } else {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Accept failed");
- }
- }
- return;
- }
-
- /*
- * fill up the remote peer port and address in the new socket structure.
- */
- socketAddressObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
- if (socketAddressObj == NULL) {
- /* should be pending exception */
- untagSocket(env, fd);
- close(newfd);
- return;
- }
-
- /*
- * Populate SocketImpl.fd.fd
- */
- socketFdObj = (*env)->GetObjectField(env, socket, psi_fdID);
- (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, newfd);
-
- (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
- (*env)->SetIntField(env, socket, psi_portID, port);
- /* also fill up the local port information */
- port = (*env)->GetIntField(env, this, psi_localportID);
- (*env)->SetIntField(env, socket, psi_localportID, port);
-}
-
-
-/*
- * Class: java_net_PlainSocketImpl
- * Method: socketAvailable
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL
-PlainSocketImpl_socketAvailable(JNIEnv *env, jobject this) {
-
- jint ret = -1;
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jint fd;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Socket closed");
- return -1;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
- /* JVM_SocketAvailable returns 0 for failure, 1 for success */
- if (!JVM_SocketAvailable(fd, &ret)){
- if (errno == ECONNRESET) {
- JNU_ThrowByName(env, "sun/net/ConnectionResetException", "");
- } else {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "ioctl FIONREAD failed");
- }
- }
- return ret;
-}
-
-/*
- * Class: java_net_PlainSocketImpl
- * Method: socketClose0
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
- jboolean useDeferredClose) {
-
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jint fd;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "socket already closed");
- return;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
- if (fd != -1) {
- int marker_fd = -1;
- if (useDeferredClose) {
- marker_fd = getMarkerFD();
- }
- if (useDeferredClose && marker_fd >= 0) {
- NET_Dup2(marker_fd, fd);
- NET_SocketClose(marker_fd);
- } else {
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
- NET_SocketClose(fd);
- }
- }
-}
-
-/*
- * Class: java_net_PlainSocketImpl
- * Method: socketShutdown
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
- jint howto)
-{
-
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jint fd;
-
- /*
- * WARNING: THIS NEEDS LOCKING. ALSO: SHOULD WE CHECK for fd being
- * -1 already?
- */
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "socket already closed");
- return;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
- JVM_SocketShutdown(fd, howto);
-}
-
-
-/*
- * Class: java_net_PlainSocketImpl
* Method: socketSetOption0
* Signature: (IZLjava/lang/Object;)V
*/
@@ -1067,56 +322,9 @@
}
-/*
- * Class: java_net_PlainSocketImpl
- * Method: socketSendUrgentData
- * Signature: (B)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketSendUrgentData(JNIEnv *env, jobject this,
- jint data) {
- /* The fd field */
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- int n, fd;
- unsigned char d = data & 0xFF;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
- return;
- } else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- /* Bug 4086704 - If the Socket associated with this file descriptor
- * was closed (sysCloseFD), the the file descriptor is set to -1.
- */
- if (fd == -1) {
- JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
- return;
- }
-
- }
- n = JVM_Send(fd, (char *)&d, 1, MSG_OOB);
- if (n == JVM_IO_ERR) {
- NET_ThrowByNameWithLastError(env, "java/io/IOException", "Write failed");
- return;
- }
- if (n == JVM_IO_INTR) {
- JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
- return;
- }
-}
-
static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(PlainSocketImpl, socketSendUrgentData, "(I)V"),
NATIVE_METHOD(PlainSocketImpl, socketGetOption, "(ILjava/lang/Object;)I"),
NATIVE_METHOD(PlainSocketImpl, socketSetOption0, "(IZLjava/lang/Object;)V"),
- NATIVE_METHOD(PlainSocketImpl, socketShutdown, "(I)V"),
- NATIVE_METHOD(PlainSocketImpl, socketClose0, "(Z)V"),
- NATIVE_METHOD(PlainSocketImpl, socketAccept, "(Ljava/net/SocketImpl;)V"),
- NATIVE_METHOD(PlainSocketImpl, socketAvailable, "()I"),
- NATIVE_METHOD(PlainSocketImpl, socketListen, "(I)V"),
- NATIVE_METHOD(PlainSocketImpl, socketBind, "(Ljava/net/InetAddress;I)V"),
- NATIVE_METHOD(PlainSocketImpl, socketConnect, "(Ljava/net/InetAddress;II)V"),
- NATIVE_METHOD(PlainSocketImpl, socketCreate, "(Z)V"),
};
void register_java_net_PlainSocketImpl(JNIEnv* env) {
diff --git a/ojluni/src/test/java/security/cert/AKISerialNumberTest.java b/ojluni/src/test/java/security/cert/AKISerialNumberTest.java
new file mode 100644
index 0000000..aae931d
--- /dev/null
+++ b/ojluni/src/test/java/security/cert/AKISerialNumberTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8025708
+ * @summary make sure a PKIX CertPathBuilder can build a path when an
+ * intermediate CA certificate contains an AKI extension with a key
+ * identifier and no serial number and the end-entity certificate contains
+ * an AKI extension with both a key identifier and a serial number.
+ */
+// Android-changed: Adapted from
+// jdk/test/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java
+// Android-changed: Added package & Test import
+package test.java.security.cert;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.*;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collections;
+
+public class AKISerialNumberTest {
+
+ private static final String ROOT_CERT =
+ "MIICfTCCAeagAwIBAgIBATANBgkqhkiG9w0BAQUFADB3MQ0wCwYDVQQDEwRSb290\n" +
+ "MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0IE9yZzEWMBQG\n" +
+ "A1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czELMAkG\n" +
+ "A1UEBhMCVVMwHhcNMTQwMjAxMDUwMDAwWhcNMjQwMjAxMDUwMDAwWjB3MQ0wCwYD\n" +
+ "VQQDEwRSb290MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0\n" +
+ "IE9yZzEWMBQGA1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVz\n" +
+ "ZXR0czELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJvL\n" +
+ "cZu6Rzf9IrduEDjJxEFv5uBvUNMlIAph7NhfmFH9puPW3Ksci4a5yTCzxI9VeVf3\n" +
+ "oYZ/UrZdF+mNZmS23RUh71X5tjMO+xew196M1xNpCRLbjcZ6i4tNdZYkdRIe8ejN\n" +
+ "sbBoD7OAvPbQqTygeG4jYjK6ODofSrba3BndNoFxAgMBAAGjGTAXMBUGA1UdEwEB\n" +
+ "/wQLMAkBAf8CBH////8wDQYJKoZIhvcNAQEFBQADgYEATvCqn69pNHv0zLiZAXk7\n" +
+ "3AKwAoza0wa+1S2rVuZGfBWbV7CxmBHbgcDDbU7/I8pQVkCwOHNkVFnBgNpMuAvU\n" +
+ "aDyrHSNS/av5d1yk5WAuGX2B9mSwZdhnAvtz2fsV1q9NptdF54EkIiKtQQmTGnr9\n" +
+ "TID8CFEk/qje+AB272B1UJw=\n";
+
+ /**
+ * This certificate contains an AuthorityKeyIdentifier with only the
+ * keyIdentifier field filled in.
+ */
+ private static final String INT_CERT_WITH_KEYID_AKI =
+ "MIICqTCCAhKgAwIBAgIBAjANBgkqhkiG9w0BAQUFADB3MQ0wCwYDVQQDEwRSb290\n" +
+ "MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0IE9yZzEWMBQG\n" +
+ "A1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czELMAkG\n" +
+ "A1UEBhMCVVMwHhcNMTQwMjAxMDUwMDAwWhcNMjQwMjAxMDUwMDAwWjCBhDEaMBgG\n" +
+ "A1UEAxMRSW50ZXJtZWRpYXRlIENBIDIxFjAUBgNVBAsTDVRlc3QgT3JnIFVuaXQx\n" +
+ "ETAPBgNVBAoTCFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5MRYwFAYD\n" +
+ "VQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEF\n" +
+ "AAOBjQAwgYkCgYEAwKTZekCqb9F9T54s2IXjkQbmLIjQamMpkUlZNrpjjNq9CpTT\n" +
+ "POkfxv2UPwzTz3Ij4XFL/kJFBLm8NUOsS5xPJ62pGoZBPw9R0iMTsTce+Fpukqnr\n" +
+ "I+8jTRaAvr0tR3pqrE6uHKg7dWYN2SsWesDia/LHhwEN38yyWtSuTTLo4hcCAwEA\n" +
+ "AaM3MDUwHwYDVR0jBBgwFoAU6gZP1pO8v7+i8gsFf1gWTf/j3PkwEgYDVR0TAQH/\n" +
+ "BAgwBgEB/wIBADANBgkqhkiG9w0BAQUFAAOBgQAQxeQruav4AqQM4gmEfrHr5hOq\n" +
+ "mB2CNJ1ZqVfpDZ8GHijncKTpjNoXzzQtV23Ge+39JHOVBNWtk+aghB3iu6xGq7Qn\n" +
+ "HlBhg9meqHFqd3igDDD/jhABL2/bEo/M9rv6saYWDFZ8nCIEE6iTLTpRRko4W2Xb\n" +
+ "DyzMzMsO1kPNrJaxRg==\n";
+
+ /**
+ * This certificate contains an AuthorityKeyIdentifier with all 3 fields
+ * (keyIdentifier, authorityCertIssuer, and authorityCertSerialNumber)
+ * filled in.
+ */
+ private static final String EE_CERT_WITH_FULL_AKI =
+ "MIIDLjCCApegAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBhDEaMBgGA1UEAxMRSW50\n" +
+ "ZXJtZWRpYXRlIENBIDIxFjAUBgNVBAsTDVRlc3QgT3JnIFVuaXQxETAPBgNVBAoT\n" +
+ "CFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5MRYwFAYDVQQIEw1NYXNz\n" +
+ "YWNodXNldHRzMQswCQYDVQQGEwJVUzAeFw0xNDAyMDEwNTAwMDBaFw0yNDAyMDEw\n" +
+ "NTAwMDBaMH0xEzARBgNVBAMTCkVuZCBFbnRpdHkxFjAUBgNVBAsTDVRlc3QgT3Jn\n" +
+ "IFVuaXQxETAPBgNVBAoTCFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5\n" +
+ "MRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG\n" +
+ "9w0BAQEFAAOBjQAwgYkCgYEAqady46PdwlKHVP1iaP11CxVyL6cDlPjpwhHCcIUv\n" +
+ "nKHbzdamqmHebDcWVBNN/I0TLNCl3ga7n8KyygSN379fG7haU8SNjpy4IDAXM0/x\n" +
+ "mwTWNTbKfJEkSoiqx1WUy2JTzRUMhgYPguQNECPxBXAdQrthZ7wQosv6Ro2ySP9O\n" +
+ "YqsCAwEAAaOBtTCBsjCBoQYDVR0jBIGZMIGWgBQdeoKxTvlTgW2KgprD69vgHV4X\n" +
+ "kKF7pHkwdzENMAsGA1UEAxMEUm9vdDEWMBQGA1UECxMNVGVzdCBPcmcgVW5pdDER\n" +
+ "MA8GA1UEChMIVGVzdCBPcmcxFjAUBgNVBAcTDVRlc3QgTG9jYWxpdHkxFjAUBgNV\n" +
+ "BAgTDU1hc3NhY2h1c2V0dHMxCzAJBgNVBAYTAlVTggECMAwGA1UdEwEB/wQCMAAw\n" +
+ "DQYJKoZIhvcNAQEFBQADgYEAuG4mM1nLF7STQWwmceELZEl49ntapH/RVoekknmd\n" +
+ "aNzcL4XQf6BTl8KFUXuThHaukQnGIzFbSZV0hrpSQ5fTN2cSZgD4Fji+HuNURmmd\n" +
+ "+Kayl0piHyO1FSbrty0TFhlVNvzKXjmMp6Jdn42KyGOSCoROQcvUWN6xkV3Hvrei\n" +
+ "0ZE=\n";
+
+ private static Base64.Decoder b64Decoder = Base64.getMimeDecoder();
+ private static CertificateFactory cf;
+
+ // Android-changed: Removed args & added @Test
+ @Test
+ public static void main() throws Exception {
+
+ cf = CertificateFactory.getInstance("X.509");
+
+ X509Certificate rootCert = getCertFromMimeEncoding(ROOT_CERT);
+ TrustAnchor anchor = new TrustAnchor(rootCert, null);
+
+ X509Certificate eeCert = getCertFromMimeEncoding(EE_CERT_WITH_FULL_AKI);
+ X509Certificate intCert = getCertFromMimeEncoding(INT_CERT_WITH_KEYID_AKI);
+
+ X509CertSelector sel = new X509CertSelector();
+ sel.setCertificate(eeCert);
+ PKIXBuilderParameters params = new PKIXBuilderParameters
+ (Collections.singleton(anchor), sel);
+ params.setRevocationEnabled(false);
+
+ ArrayList<X509Certificate> certs = new ArrayList<>();
+ certs.add(intCert);
+ certs.add(eeCert);
+ CollectionCertStoreParameters ccsp =
+ new CollectionCertStoreParameters(certs);
+ CertStore cs = CertStore.getInstance("Collection", ccsp);
+ params.addCertStore(cs);
+
+ CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
+ CertPathBuilderResult res = cpb.build(params);
+ }
+
+ private static X509Certificate getCertFromMimeEncoding(String encoded)
+ throws CertificateException
+ {
+ byte[] bytes = b64Decoder.decode(encoded);
+ ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
+ return (X509Certificate)cf.generateCertificate(stream);
+ }
+}
\ No newline at end of file
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index 4285911..3b38617 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1610,6 +1610,8 @@
ojluni/src/main/java/sun/security/provider/certpath/X509CertificatePair.java \
ojluni/src/main/java/sun/security/provider/X509Factory.java \
ojluni/src/main/java/sun/security/timestamp/TimestampToken.java \
+ ojluni/src/main/java/sun/security/util/AnchorCertificates.java \
+ ojluni/src/main/java/sun/security/util/CertConstraintParameters.java \
ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java \
ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java \
ojluni/src/main/java/sun/security/util/BitArray.java \
diff --git a/tools/docs/crypto/crypto_docs.py b/tools/docs/crypto/crypto_docs.py
new file mode 100644
index 0000000..d1f220d
--- /dev/null
+++ b/tools/docs/crypto/crypto_docs.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+'''Utility functions for crypto doc updating tools.'''
+
+import json
+
+
+def load_json(filename):
+ '''Returns an object containing the JSON data from the provided file.'''
+ f = open(filename)
+ # JSON doesn't allow comments, but we have some header docs in our file,
+ # so strip comments out before parsing
+ stripped_contents = ''
+ for line in f:
+ if not line.strip().startswith('#'):
+ stripped_contents += line
+ data = json.loads(stripped_contents)
+ f.close()
+ return data
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index d50eb2c..38834d9 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -16,7 +16,7 @@
},
{
"deprecated": "true",
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1-8"
},
{
@@ -45,7 +45,7 @@
"supported_api_levels": "1+"
},
{
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1+"
},
{
@@ -74,43 +74,43 @@
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_128",
+ "name": "PBEwithHmacSHA1AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_256",
+ "name": "PBEwithHmacSHA1AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_128",
+ "name": "PBEwithHmacSHA224AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_256",
+ "name": "PBEwithHmacSHA224AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_128",
+ "name": "PBEwithHmacSHA256AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_256",
+ "name": "PBEwithHmacSHA256AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_128",
+ "name": "PBEwithHmacSHA384AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_256",
+ "name": "PBEwithHmacSHA384AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_128",
+ "name": "PBEwithHmacSHA512AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_256",
+ "name": "PBEwithHmacSHA512AndAES_256",
"supported_api_levels": "26+"
},
{
@@ -145,7 +145,7 @@
{
"algorithms": [
{
- "name": "COLLECTION",
+ "name": "Collection",
"supported_api_levels": "1+"
}
],
@@ -163,6 +163,411 @@
{
"algorithms": [
{
+ "name": "AES/CBC/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CBC/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CBC/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CFB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CFB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CFB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTR/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTR/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTR/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTS/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTS/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTS/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/ECB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/ECB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/ECB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/GCM/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "AES/OFB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/OFB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/OFB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES_128/CBC/NoPadding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/CBC/PKCS5Padding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/ECB/NoPadding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/ECB/PKCS5Padding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/GCM/NoPadding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/CBC/NoPadding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/CBC/PKCS5Padding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/ECB/NoPadding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/ECB/PKCS5Padding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/GCM/NoPadding",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "ARC4/ECB/NoPadding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CBC/ISO10126Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CBC/NoPadding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CBC/PKCS5Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CFB/ISO10126Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CFB/NoPadding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CFB/PKCS5Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTR/ISO10126Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTR/NoPadding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTR/PKCS5Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTS/ISO10126Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTS/NoPadding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTS/PKCS5Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/ECB/ISO10126Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/ECB/NoPadding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/ECB/PKCS5Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/OFB/ISO10126Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/OFB/NoPadding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/OFB/PKCS5Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "DES/CBC/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CBC/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CBC/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CFB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CFB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CFB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTR/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTR/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTR/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTS/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTS/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTS/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/ECB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/ECB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/ECB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/OFB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/OFB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/OFB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CBC/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CBC/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CBC/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CFB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CFB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CFB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CTR/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CTR/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CTR/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CTS/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CTS/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/CTS/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/ECB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/ECB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/ECB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/OFB/ISO10126Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/OFB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESede/OFB/PKCS5Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/ECB/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/ECB/OAEPPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/ECB/OAEPwithSHA-1andMGF1Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/ECB/OAEPwithSHA-224andMGF1Padding",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/ECB/OAEPwithSHA-256andMGF1Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/ECB/OAEPwithSHA-384andMGF1Padding",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/ECB/OAEPwithSHA-512andMGF1Padding",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/ECB/PKCS1Padding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/NONE/NoPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/NONE/OAEPPadding",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/NONE/OAEPwithSHA-1andMGF1Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/NONE/OAEPwithSHA-224andMGF1Padding",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/NONE/OAEPwithSHA-256andMGF1Padding",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/NONE/OAEPwithSHA-384andMGF1Padding",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/NONE/OAEPwithSHA-512andMGF1Padding",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/NONE/PKCS1Padding",
+ "supported_api_levels": "1+"
+ }
+ ],
+ "name": "Cipher"
+ },
+ {
+ "algorithms": [
+ {
"name": "DH",
"supported_api_levels": "1+"
},
@@ -223,36 +628,36 @@
"supported_api_levels": "1+"
},
{
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1+"
},
{
"deprecated": "true",
- "name": "DESEDEWRAP",
+ "name": "DESedeWRAP",
"supported_api_levels": "1-8"
},
{
- "name": "HMACMD5",
+ "name": "HmacMD5",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA1",
+ "name": "HmacSHA1",
"supported_api_levels": "11+"
},
{
- "name": "HMACSHA224",
+ "name": "HmacSHA224",
"supported_api_levels": "1-8,22+"
},
{
- "name": "HMACSHA256",
+ "name": "HmacSHA256",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA384",
+ "name": "HmacSHA384",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA512",
+ "name": "HmacSHA512",
"supported_api_levels": "1+"
},
{
@@ -296,11 +701,11 @@
{
"algorithms": [
{
- "name": "ANDROIDCASTORE",
+ "name": "AndroidCAStore",
"supported_api_levels": "14+"
},
{
- "name": "ANDROIDKEYSTORE",
+ "name": "AndroidKeyStore",
"supported_api_levels": "18+"
},
{
@@ -313,7 +718,7 @@
"supported_api_levels": "1+"
},
{
- "name": "BOUNCYCASTLE",
+ "name": "BouncyCastle",
"supported_api_levels": "1+"
},
{
@@ -332,21 +737,6 @@
"algorithms": [
{
"deprecated": "true",
- "name": "DESEDEMAC",
- "supported_api_levels": "1-8"
- },
- {
- "deprecated": "true",
- "name": "DESEDEMAC/CFB8",
- "supported_api_levels": "1-8"
- },
- {
- "deprecated": "true",
- "name": "DESEDEMAC64",
- "supported_api_levels": "1-8"
- },
- {
- "deprecated": "true",
"name": "DESMAC",
"supported_api_levels": "1-8"
},
@@ -357,31 +747,46 @@
},
{
"deprecated": "true",
- "name": "DESWITHISO9797",
+ "name": "DESedeMAC",
"supported_api_levels": "1-8"
},
{
- "name": "HMACMD5",
+ "deprecated": "true",
+ "name": "DESedeMAC/CFB8",
+ "supported_api_levels": "1-8"
+ },
+ {
+ "deprecated": "true",
+ "name": "DESedeMAC64",
+ "supported_api_levels": "1-8"
+ },
+ {
+ "deprecated": "true",
+ "name": "DESwithISO9797",
+ "supported_api_levels": "1-8"
+ },
+ {
+ "name": "HmacMD5",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA1",
+ "name": "HmacSHA1",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA224",
+ "name": "HmacSHA224",
"supported_api_levels": "1-8,22+"
},
{
- "name": "HMACSHA256",
+ "name": "HmacSHA256",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA384",
+ "name": "HmacSHA384",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA512",
+ "name": "HmacSHA512",
"supported_api_levels": "1+"
},
{
@@ -390,27 +795,27 @@
"supported_api_levels": "1-8"
},
{
- "name": "PBEWITHHMACSHA",
+ "name": "PBEwithHmacSHA",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA1",
+ "name": "PBEwithHmacSHA1",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA224",
+ "name": "PBEwithHmacSHA224",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256",
+ "name": "PBEwithHmacSHA256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384",
+ "name": "PBEwithHmacSHA384",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512",
+ "name": "PBEwithHmacSHA512",
"supported_api_levels": "26+"
}
],
@@ -448,7 +853,7 @@
{
"algorithms": [
{
- "name": "DEFAULT",
+ "name": "Default",
"supported_api_levels": "10+"
},
{
@@ -457,7 +862,7 @@
},
{
"deprecated": "true",
- "name": "SSLV3",
+ "name": "SSLv3",
"supported_api_levels": "10-25"
},
{
@@ -465,15 +870,15 @@
"supported_api_levels": "1+"
},
{
- "name": "TLSV1",
+ "name": "TLSv1",
"supported_api_levels": "10+"
},
{
- "name": "TLSV1.1",
+ "name": "TLSv1.1",
"supported_api_levels": "16+"
},
{
- "name": "TLSV1.2",
+ "name": "TLSv1.2",
"supported_api_levels": "16+"
}
],
@@ -490,175 +895,175 @@
"supported_api_levels": "1+"
},
{
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA1",
+ "name": "HmacSHA1",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA224",
+ "name": "HmacSHA224",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA256",
+ "name": "HmacSHA256",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA384",
+ "name": "HmacSHA384",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA512",
+ "name": "HmacSHA512",
"supported_api_levels": "23+"
},
{
- "name": "PBEWITHHMACSHA1",
+ "name": "PBEwithHmacSHA1",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_128",
+ "name": "PBEwithHmacSHA1AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_256",
+ "name": "PBEwithHmacSHA1AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_128",
+ "name": "PBEwithHmacSHA224AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_256",
+ "name": "PBEwithHmacSHA224AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_128",
+ "name": "PBEwithHmacSHA256AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_256",
+ "name": "PBEwithHmacSHA256AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_128",
+ "name": "PBEwithHmacSHA384AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_256",
+ "name": "PBEwithHmacSHA384AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_128",
+ "name": "PBEwithHmacSHA512AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_256",
+ "name": "PBEwithHmacSHA512AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
+ "name": "PBEwithMD5AND128BITAES-CBC-OPENSSL",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
+ "name": "PBEwithMD5AND192BITAES-CBC-OPENSSL",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5AND256BITAES-CBC-OPENSSL",
+ "name": "PBEwithMD5AND256BITAES-CBC-OPENSSL",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5ANDDES",
+ "name": "PBEwithMD5ANDDES",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5ANDRC2",
+ "name": "PBEwithMD5ANDRC2",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA1ANDDES",
+ "name": "PBEwithSHA1ANDDES",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA1ANDRC2",
+ "name": "PBEwithSHA1ANDRC2",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA256AND128BITAES-CBC-BC",
+ "name": "PBEwithSHA256AND128BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA256AND192BITAES-CBC-BC",
+ "name": "PBEwithSHA256AND192BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA256AND256BITAES-CBC-BC",
+ "name": "PBEwithSHA256AND256BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND128BITAES-CBC-BC",
+ "name": "PBEwithSHAAND128BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND128BITRC2-CBC",
+ "name": "PBEwithSHAAND128BITRC2-CBC",
"supported_api_levels": "10+"
},
{
- "name": "PBEWITHSHAAND128BITRC4",
+ "name": "PBEwithSHAAND128BITRC4",
"supported_api_levels": "10+"
},
{
- "name": "PBEWITHSHAAND192BITAES-CBC-BC",
+ "name": "PBEwithSHAAND192BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND2-KEYTRIPLEDES-CBC",
+ "name": "PBEwithSHAAND2-KEYTRIPLEDES-CBC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND256BITAES-CBC-BC",
+ "name": "PBEwithSHAAND256BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND3-KEYTRIPLEDES-CBC",
+ "name": "PBEwithSHAAND3-KEYTRIPLEDES-CBC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND40BITRC2-CBC",
+ "name": "PBEwithSHAAND40BITRC2-CBC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND40BITRC4",
+ "name": "PBEwithSHAAND40BITRC4",
"supported_api_levels": "10+"
},
{
- "name": "PBEWITHSHAANDTWOFISH-CBC",
+ "name": "PBEwithSHAANDTWOFISH-CBC",
"supported_api_levels": "10+"
},
{
- "name": "PBKDF2WITHHMACSHA1",
+ "name": "PBKDF2withHmacSHA1",
"supported_api_levels": "10+"
},
{
- "name": "PBKDF2WITHHMACSHA1AND8BIT",
+ "name": "PBKDF2withHmacSHA1And8BIT",
"supported_api_levels": "19+"
},
{
- "name": "PBKDF2WITHHMACSHA224",
+ "name": "PBKDF2withHmacSHA224",
"supported_api_levels": "26+"
},
{
- "name": "PBKDF2WITHHMACSHA256",
+ "name": "PBKDF2withHmacSHA256",
"supported_api_levels": "26+"
},
{
- "name": "PBKDF2WITHHMACSHA384",
+ "name": "PBKDF2withHmacSHA384",
"supported_api_levels": "26+"
},
{
- "name": "PBKDF2WITHHMACSHA512",
+ "name": "PBKDF2withHmacSHA512",
"supported_api_levels": "26+"
}
],
@@ -680,7 +1085,7 @@
"supported_api_levels": "1+"
},
{
- "name": "DSAWITHSHA1",
+ "name": "DSAwithSHA1",
"supported_api_levels": "1+"
},
{
@@ -693,38 +1098,38 @@
"supported_api_levels": "11+"
},
{
- "name": "ECDSAWITHSHA1",
+ "name": "ECDSAwithSHA1",
"supported_api_levels": "11+"
},
{
"deprecated": "true",
- "name": "MD2WITHRSA",
+ "name": "MD2withRSA",
"supported_api_levels": "1-3"
},
{
"deprecated": "true",
- "name": "MD4WITHRSA",
+ "name": "MD4withRSA",
"supported_api_levels": "1-8"
},
{
- "name": "MD5WITHRSA",
+ "name": "MD5withRSA",
"supported_api_levels": "1+"
},
{
"deprecated": "true",
- "name": "MD5WITHRSA/ISO9796-2",
+ "name": "MD5withRSA/ISO9796-2",
"supported_api_levels": "1-8"
},
{
- "name": "NONEWITHDSA",
+ "name": "NONEwithDSA",
"supported_api_levels": "1+"
},
{
- "name": "NONEWITHECDSA",
+ "name": "NONEwithECDSA",
"supported_api_levels": "11+"
},
{
- "name": "NONEWITHRSA",
+ "name": "NONEwithRSA",
"supported_api_levels": "17+"
},
{
@@ -733,80 +1138,80 @@
"supported_api_levels": "1-8"
},
{
- "name": "SHA1WITHDSA",
+ "name": "SHA1withDSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA1WITHECDSA",
+ "name": "SHA1withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA1WITHRSA",
+ "name": "SHA1withRSA",
"supported_api_levels": "1+"
},
{
"deprecated": "true",
- "name": "SHA1WITHRSA/ISO9796-2",
+ "name": "SHA1withRSA/ISO9796-2",
"supported_api_levels": "1-8"
},
{
- "name": "SHA1WITHRSA/PSS",
+ "name": "SHA1withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA224WITHDSA",
+ "name": "SHA224withDSA",
"supported_api_levels": "20+"
},
{
- "name": "SHA224WITHECDSA",
+ "name": "SHA224withECDSA",
"supported_api_levels": "20+"
},
{
- "name": "SHA224WITHRSA",
+ "name": "SHA224withRSA",
"supported_api_levels": "20+"
},
{
- "name": "SHA224WITHRSA/PSS",
+ "name": "SHA224withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA256WITHDSA",
+ "name": "SHA256withDSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA256WITHECDSA",
+ "name": "SHA256withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA256WITHRSA",
+ "name": "SHA256withRSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA256WITHRSA/PSS",
+ "name": "SHA256withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA384WITHECDSA",
+ "name": "SHA384withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA384WITHRSA",
+ "name": "SHA384withRSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA384WITHRSA/PSS",
+ "name": "SHA384withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA512WITHECDSA",
+ "name": "SHA512withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA512WITHRSA",
+ "name": "SHA512withRSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA512WITHRSA/PSS",
+ "name": "SHA512withRSA/PSS",
"supported_api_levels": "23+"
}
],
@@ -822,5 +1227,5 @@
"name": "TrustManagerFactory"
}
],
- "last_updated": "2017-03-14 15:13:50 UTC"
+ "last_updated": "2017-03-21 16:04:30 UTC"
}
\ No newline at end of file
diff --git a/tools/docs/crypto/format_supported_algorithm_table.py b/tools/docs/crypto/format_supported_algorithm_table.py
index f07f9d9..3b23066 100755
--- a/tools/docs/crypto/format_supported_algorithm_table.py
+++ b/tools/docs/crypto/format_supported_algorithm_table.py
@@ -20,8 +20,10 @@
reflect the crypto algorithm support shown in the provided data file.
"""
-import json
-import sys
+import argparse
+import operator
+
+import crypto_docs
def sort_by_name(seq):
@@ -29,40 +31,155 @@
def main():
- if len(sys.argv) < 2:
- print 'Must supply argument to data file.'
- sys.exit(1)
- data = json.load(open(sys.argv[1]))
+ parser = argparse.ArgumentParser(description='Output algorithm support HTML tables')
+ parser.add_argument('--for_javadoc',
+ action='store_true',
+ help='If specified, format for inclusion in class documentation')
+ parser.add_argument('file',
+ help='The JSON file to use for data')
+ args = parser.parse_args()
+
+ output = []
+ data = crypto_docs.load_json(args.file)
categories = sort_by_name(data['categories'])
- print '<h2 id="SupportedAlgorithms">Supported Algorithms</h2>'
- print
- print '<ul>'
+ output.append('<h2 id="SupportedAlgorithms">Supported Algorithms</h2>')
+ output.append('')
+ output.append('<ul>')
for category in categories:
- print (' <li><a href="#Supported{name}">'
+ output.append(' <li><a href="#Supported{name}">'
'<code>{name}</code></a></li>'.format(**category))
- print '</ul>'
+ output.append('</ul>')
for category in categories:
- print '''
-<h3 id="Supported{name}">{name}</h3>
-<table>
- <thead>
- <th>Algorithm</th>
- <th>Supported API Levels</th>
- </thead>
- <tbody>'''.format(**category)
- algorithms = sort_by_name(category['algorithms'])
- for algorithm in algorithms:
- dep_class = ''
- if 'deprecated' in algorithm and algorithm['deprecated']:
- dep_class = ' class="deprecated"'
- print '''
- <tr{deprecated_class}>
- <td>{name}</td>
- <td>{supported_api_levels}</td>
- </tr>'''.format(deprecated_class=dep_class, **algorithm)
- print '''
- </tbody>
-</table>'''
+ if category['name'] == 'Cipher':
+ # We display ciphers in a four-column table to conserve space and
+ # so that it's more comprehensible. To do this, we have to
+ # collapse all our ciphers into "equivalence classes" of a sort.
+
+ # First, collect the relevant data for each algorithm into a tuple.
+ # The mode and padding are in lists because we are going to collapse
+ # multiple tuples with those in later steps.
+ algorithms = sort_by_name(category['algorithms'])
+ tuples = []
+ for algorithm in algorithms:
+ name, mode, padding = algorithm['name'].split('/')
+ tuples.append((
+ name,
+ [mode],
+ [padding],
+ algorithm['supported_api_levels'],
+ 'deprecated' in algorithm and algorithm['deprecated']))
+ # Sort the tuples by all items except padding, then collapse
+ # items with all non-padding values the same (which will always be
+ # neighboring items) into a single item.
+ tuples.sort(key=operator.itemgetter(0, 1, 3, 4))
+ i = 0
+ while i < len(tuples) - 1:
+ if (tuples[i][0] == tuples[i+1][0]
+ and tuples[i][1] == tuples[i+1][1]
+ and tuples[i][3] == tuples[i+1][3]
+ and tuples[i][4] == tuples[i+1][4]):
+ tuples[i][2].extend(tuples[i+1][2])
+ del tuples[i+1]
+ else:
+ i += 1
+ # Do the same thing as above, but with modes.
+ tuples.sort(key=operator.itemgetter(0, 2, 3, 4))
+ i = 0
+ while i < len(tuples) - 1:
+ if (tuples[i][0] == tuples[i+1][0]
+ and tuples[i][2] == tuples[i+1][2]
+ and tuples[i][3] == tuples[i+1][3]
+ and tuples[i][4] == tuples[i+1][4]):
+ tuples[i][1].extend(tuples[i+1][1])
+ del tuples[i+1]
+ else:
+ i += 1
+ # Display the table with rowspans for those entries where all the
+ # items have the same algorithm, mode, etc
+ output.append('<h3 id="Supported{name}">{name}</h3>'.format(**category))
+ output.append('<table>')
+ output.append(' <thead>')
+ output.append(' <tr>')
+ output.append(' <th>Algorithm</th>')
+ output.append(' <th>Modes</th>')
+ output.append(' <th>Paddings</th>')
+ output.append(' <th>Supported API Levels</th>')
+ output.append(' </tr>')
+ output.append(' </thead>')
+ output.append(' <tbody>')
+ tuples.sort(key=operator.itemgetter(0, 4, 1, 2, 3))
+ i = 0
+ cur_deprecated = None
+ cur_algorithm = None
+ cur_mode = None
+ while i < len(tuples):
+ row = tuples[i]
+ if row[4] != cur_deprecated:
+ cur_deprecated = row[4]
+ cur_algorithm = None
+ cur_mode = None
+ if cur_deprecated:
+ output.append(' <tr class="deprecated">')
+ else:
+ output.append(' <tr>')
+ if row[0] != cur_algorithm:
+ cur_algorithm = row[0]
+ cur_mode = None
+ j = i + 1
+ while (j < len(tuples)
+ and tuples[j][4] == cur_deprecated
+ and tuples[j][0] == cur_algorithm):
+ j += 1
+ rowspan = j - i
+ if rowspan > 1:
+ output.append(' <td rowspan="%d">%s</td>' % (rowspan, cur_algorithm))
+ else:
+ output.append(' <td>%s</td>' % cur_algorithm)
+ if row[1] != cur_mode:
+ cur_mode = row[1]
+ j = i + 1
+ while (j < len(tuples)
+ and tuples[j][4] == cur_deprecated
+ and tuples[j][0] == cur_algorithm
+ and tuples[j][1] == cur_mode):
+ j += 1
+ rowspan = j - i
+ modestring = '<br>'.join(cur_mode)
+ if rowspan > 1:
+ output.append(' <td rowspan="%d">%s</td>' % (rowspan, modestring))
+ else:
+ output.append(' <td>%s</td>' % modestring)
+ output.append(' <td>%s</td>' % '<br>'.join(row[2]))
+ output.append(' <td>%s</td>' % row[3])
+ output.append(' </tr>')
+ i += 1
+ output.append(' </tbody>')
+ output.append('</table>')
+ else:
+ output.append('<h3 id="Supported{name}">{name}</h3>'.format(**category))
+ output.append('<table>')
+ output.append(' <thead>')
+ output.append(' <tr>')
+ output.append(' <th>Algorithm</th>')
+ output.append(' <th>Supported API Levels</th>')
+ output.append(' </tr>')
+ output.append(' </thead>')
+ output.append(' <tbody>')
+ algorithms = sort_by_name(category['algorithms'])
+ for algorithm in algorithms:
+ if 'deprecated' in algorithm and algorithm['deprecated']:
+ output.append(' <tr class="deprecated">')
+ else:
+ output.append(' <tr>')
+ output.append(' <td>{name}</td>'.format(**algorithm))
+ output.append(' <td>{supported_api_levels}</td>'.format(**algorithm))
+ output.append(' </tr>')
+ output.append(' </tbody>')
+ output.append('</table>')
+ if args.for_javadoc:
+ for i in range(len(output)):
+ output[i] = ' * ' + output[i]
+ print '\n'.join(output)
if __name__ == '__main__':
diff --git a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
index 34aed4b..1cd8646 100644
--- a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
+++ b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
@@ -16,6 +16,7 @@
package libcore.java.security;
+import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
@@ -25,6 +26,8 @@
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
/**
* Prints a list of all algorithms provided by security providers. Intended to be run
@@ -34,15 +37,50 @@
*/
public class ListProviders {
+ private static final boolean SHOW_PROVIDER = false;
+
// These algorithms were previously provided, but now are aliases for a different
// algorithm. For documentation purposes, we want to continue having them show up
// as supported.
- private static final Set<String> KNOWN_ALIASES = new HashSet<>(Arrays.asList(new String[]{
+ private static final Set<String> KNOWN_ALIASES = new TreeSet<>(Arrays.asList(new String[]{
"Alg.Alias.Signature.DSA",
"Alg.Alias.Signature.DSAwithSHA1",
"Alg.Alias.Signature.ECDSA",
"Alg.Alias.Signature.ECDSAwithSHA1",
}));
+
+ // Ciphers come in algorithm/mode/padding combinations, and not all combinations are explicitly
+ // registered by the providers (sometimes only the base algorithm is registered). While there
+ // is a mechanism for providers to specify which modes and/or paddings are supported for a
+ // given algorithm, none of our providers use it. Thus, when a base algorithm is seen, all
+ // combinations of modes and paddings will be tried to see which ones are supported.
+ private static final Set<String> CIPHER_MODES = new TreeSet<>(Arrays.asList(new String[]{
+ "CBC",
+ "CFB",
+ "CTR",
+ "CTS",
+ "ECB",
+ "GCM",
+ "OFB",
+ "NONE",
+ }));
+ private static final Set<String> CIPHER_PADDINGS = new TreeSet<>(Arrays.asList(new String[]{
+ "NoPadding",
+ "OAEPPadding",
+ "OAEPwithSHA-1andMGF1Padding",
+ "OAEPwithSHA-224andMGF1Padding",
+ "OAEPwithSHA-256andMGF1Padding",
+ "OAEPwithSHA-384andMGF1Padding",
+ "OAEPwithSHA-512andMGF1Padding",
+ "PKCS1Padding",
+ "PKCS5Padding",
+ "ISO10126Padding",
+ }));
+
+ private static void print(Provider p, String type, String algorithm) {
+ System.out.println((SHOW_PROVIDER ? p.getName() + ": " : "") + type + " " + algorithm);
+ }
+
public static void main(String[] argv) {
System.out.println("BEGIN ALGORITHM LIST");
for (Provider p : Security.getProviders()) {
@@ -58,12 +96,33 @@
});
services.addAll(p.getServices());
for (Provider.Service s : services) {
- System.out.println(s.getType() + " " + s.getAlgorithm());
+ if (s.getType().equals("Cipher") && s.getAlgorithm().startsWith("PBE")) {
+ // PBE ciphers are a mess and generally don't do anything but delegate
+ // to the underlying cipher. We don't want to document them.
+ continue;
+ }
+ if (s.getType().equals("Cipher") && s.getAlgorithm().indexOf('/') == -1) {
+ for (String mode : CIPHER_MODES) {
+ for (String padding : CIPHER_PADDINGS) {
+ try {
+ String name = s.getAlgorithm() + "/" + mode + "/" + padding;
+ Cipher.getInstance(name, p);
+ print(p, s.getType(), name);
+ } catch (NoSuchAlgorithmException
+ |NoSuchPaddingException
+ |IllegalArgumentException e) {
+ // This combination doesn't work
+ }
+ }
+ }
+ } else {
+ print(p, s.getType(), s.getAlgorithm());
+ }
}
for (String alias : KNOWN_ALIASES) {
if (p.containsKey(alias)) {
String[] elements = alias.split("\\."); // Split takes a regex
- System.out.println(elements[2] + " " + elements[3]);
+ print(p, elements[2], elements[3]);
}
}
}
diff --git a/tools/docs/crypto/update_crypto_support.py b/tools/docs/crypto/update_crypto_support.py
index c8d19df..207e0f4 100755
--- a/tools/docs/crypto/update_crypto_support.py
+++ b/tools/docs/crypto/update_crypto_support.py
@@ -24,12 +24,13 @@
import argparse
import collections
-import copy
import datetime
import json
+import re
import sys
-# TODO(b/35793879): Support more categories
+import crypto_docs
+
SUPPORTED_CATEGORIES = [
'AlgorithmParameterGenerator',
'AlgorithmParameters',
@@ -37,6 +38,7 @@
'CertPathBuilder',
'CertPathValidator',
'CertStore',
+ 'Cipher',
'KeyAgreement',
'KeyFactory',
'KeyGenerator',
@@ -61,6 +63,14 @@
return None
+def find_by_normalized_name(seq, name):
+ """Returns the first element in seq with the given normalized name."""
+ for item in seq:
+ if normalize_name(item['name']) == name:
+ return item
+ return None
+
+
def sort_by_name(seq):
"""Returns a copy of the input sequence sorted by name."""
return sorted(seq, key=lambda x: x['name'])
@@ -73,8 +83,31 @@
# reverse. X.509 is the official name of the standard, so use that.
if name == "X509":
name = "X.509"
+ # PKCS5PADDING and PKCS7PADDING are the same thing (more accurately, PKCS#5
+ # is a special case of PKCS#7), but providers are inconsistent in their
+ # naming. Use PKCS5PADDING because that's what our docs have used
+ # historically.
+ if name.endswith("/PKCS7PADDING"):
+ name = name[:-1 * len("/PKCS7PADDING")] + "/PKCS5PADDING"
return name
+
+def fix_name_caps_for_output(name):
+ """Returns a version of the given algorithm name with capitalization fixed."""
+ # It's important that this must only change the capitalization of the
+ # name, not any of its text, otherwise future runs won't be able to
+ # match this name with the name coming from the device.
+
+ # We current make the following capitalization fixes
+ # DESede (not DESEDE)
+ # FOOwithBAR (not FOOWITHBAR or FOOWithBAR)
+ # Hmac (not HMAC)
+ name = re.sub('WITH', 'with', name, flags=re.I)
+ name = re.sub('DESEDE', 'DESede', name, flags=re.I)
+ name = re.sub('HMAC', 'Hmac', name, flags=re.I)
+ return name
+
+
def get_current_data(f):
"""Returns a map of the algorithms in the given input.
@@ -86,12 +119,17 @@
The returned algorithms will have their names normalized.
+ Returns:
+ A dict of categories to lists of normalized algorithm names and a
+ dict of normalized algorithm names to original algorithm names.
+
Raises:
EOFError: If either the BEGIN or END sentinel lines are not present.
ValueError: If a line between the BEGIN and END sentinel lines is not
made up of two identifiers separated by whitespace.
"""
current_data = collections.defaultdict(list)
+ name_dict = {}
saw_begin = False
saw_end = False
@@ -107,7 +145,9 @@
category, algorithm = line.split()
if category not in SUPPORTED_CATEGORIES:
continue
- current_data[category].append(normalize_name(algorithm))
+ normalized_name = normalize_name(algorithm)
+ current_data[category].append(normalized_name)
+ name_dict[normalized_name] = algorithm
if not saw_begin:
raise EOFError(
@@ -115,10 +155,10 @@
if not saw_end:
raise EOFError(
'Reached the end of input without encountering the end sentinel')
- return dict(current_data)
+ return dict(current_data), name_dict
-def update_data(prev_data, current_data, api_level, date):
+def update_data(prev_data, current_data, name_dict, api_level, date):
"""Returns a copy of prev_data, modified to take into account current_data.
Updates the algorithm support metadata structure by starting with the
@@ -143,14 +183,20 @@
current_category = (
current_data[category] if category in current_data else [])
new_category = {'name': category, 'algorithms': []}
- prev_algorithms = [x['name'] for x in prev_category['algorithms']]
+ prev_algorithms = [normalize_name(x['name']) for x in prev_category['algorithms']]
alg_union = set(prev_algorithms) | set(current_category)
for alg in alg_union:
- new_algorithm = {'name': alg}
+ prev_alg = find_by_normalized_name(prev_category['algorithms'], alg)
+ if alg in name_dict:
+ new_algorithm = {'name': name_dict[alg]}
+ elif prev_alg is not None:
+ new_algorithm = {'name': prev_alg['name']}
+ else:
+ new_algorithm = {'name': alg}
+ new_algorithm['name'] = fix_name_caps_for_output(new_algorithm['name'])
new_level = None
if alg in current_category and alg in prev_algorithms:
# Both old and new have it, just ensure the API level is right
- prev_alg = find_by_name(prev_category['algorithms'], alg)
if prev_alg['supported_api_levels'].endswith('+'):
new_level = prev_alg['supported_api_levels']
else:
@@ -159,7 +205,6 @@
elif alg in prev_algorithms:
# Only in the old set, so ensure the API level is marked
# as ending
- prev_alg = find_by_name(prev_category['algorithms'], alg)
if prev_alg['supported_api_levels'].endswith('+'):
# The algorithm is newly missing, so modify the support
# to end at the previous level
@@ -199,20 +244,13 @@
help='The JSON file to update')
args = parser.parse_args()
- f = open(args.file)
- # JSON doesn't allow comments, but we have some header docs in our file,
- # so strip comments out before parsing
- stripped_contents = ''
- for line in f:
- if not line.strip().startswith('#'):
- stripped_contents += line
- prev_data = json.loads(stripped_contents)
- f.close()
+ prev_data = crypto_docs.load_json(args.file)
- current_data = get_current_data(sys.stdin)
+ current_data, name_dict = get_current_data(sys.stdin)
new_data = update_data(prev_data,
current_data,
+ name_dict,
args.api_level,
datetime.datetime.utcnow())
diff --git a/tools/docs/crypto/update_crypto_support_test.py b/tools/docs/crypto/update_crypto_support_test.py
index cb8fe87..4fbc210 100755
--- a/tools/docs/crypto/update_crypto_support_test.py
+++ b/tools/docs/crypto/update_crypto_support_test.py
@@ -20,10 +20,11 @@
import update_crypto_support
-def do_update_data(prev_data, current_data):
+def do_update_data(prev_data, current_data, name_dict={}):
return update_crypto_support.update_data(
prev_data,
current_data,
+ name_dict,
72,
datetime.datetime.utcfromtimestamp(1234567890))
@@ -88,8 +89,12 @@
OtherThing Mary
END ALGORITHM LIST
''')),
- {'Mac': ['BOB', 'JONES', 'AMY'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['BOB', 'JONES', 'AMY'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'BOB': 'Bob',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
self.assertEqual(update_crypto_support.get_current_data(
StringIO.StringIO(
'''
@@ -102,8 +107,12 @@
OtherThing Mary
END ALGORITHM LIST
''')),
- {'Mac': ['DUPE', 'JONES', 'AMY', 'DUPE'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['DUPE', 'JONES', 'AMY', 'DUPE'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'DUPE': 'Dupe',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
self.assertEqual(update_crypto_support.get_current_data(
StringIO.StringIO(
'''
@@ -117,8 +126,12 @@
END ALGORITHM LIST
Mac AlsoNotAValue
''')),
- {'Mac': ['BOB', 'JONES', 'AMY'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['BOB', 'JONES', 'AMY'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'BOB': 'Bob',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
self.assertEqual(update_crypto_support.get_current_data(
StringIO.StringIO(
'''
@@ -132,8 +145,12 @@
OtherThing Mary
END ALGORITHM LIST
''')),
- {'Mac': ['BOB', 'JONES', 'AMY'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['BOB', 'JONES', 'AMY'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'BOB': 'Bob',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
with self.assertRaises(EOFError):
update_crypto_support.get_current_data(StringIO.StringIO(
'''
@@ -342,6 +359,59 @@
'api_level': '72',
'last_updated': LAST_UPDATED_TEXT})
+ def test_update_name_matching(self):
+ self.assertEqual(
+ do_update_data(
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22',
+ 'deprecated': 'true'},
+ {'name': 'SHA-3',
+ 'supported_api_levels': '7+'}]}]},
+ {'MessageDigest': ['SHA-1', 'SHA-2', 'SHA-3']},
+ {'SHA-1': 'Sha-1', 'SHA-2': 'Sha-2', 'SHA-3': 'Sha-3'}),
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'Sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22,72+'},
+ {'name': 'Sha-3',
+ 'supported_api_levels': '7+'}]}],
+ 'api_level': '72',
+ 'last_updated': LAST_UPDATED_TEXT})
+ self.assertEqual(
+ do_update_data(
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22',
+ 'deprecated': 'true'},
+ {'name': 'SHA-3',
+ 'supported_api_levels': '7+'}]}]},
+ {'MessageDigest': ['SHA-1', 'SHA-3']},
+ {'SHA-1': 'Sha-1', 'SHA-3': 'Sha-3'}),
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'Sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22',
+ 'deprecated': 'true'},
+ {'name': 'Sha-3',
+ 'supported_api_levels': '7+'}]}],
+ 'api_level': '72',
+ 'last_updated': LAST_UPDATED_TEXT})
+
if __name__ == '__main__':
unittest.main()
diff --git a/tools/upstream/oj_upstream_comparison.py b/tools/upstream/oj_upstream_comparison.py
new file mode 100755
index 0000000..deab5fb
--- /dev/null
+++ b/tools/upstream/oj_upstream_comparison.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Helps compare openjdk_java_files contents against upstream file contents.
+
+Outputs a tab-separated table comparing each openjdk_java_files entry
+against OpenJDK upstreams. This can help verify updates to later upstreams
+or focus attention towards files that may have been missed in a previous
+update (http://b/36461944) or are otherwise surprising (http://b/36429512).
+
+ - Identifies each file as identical to, different from or missing from
+ each upstream; diffs are not produced.
+ - Optionally, copies all openjdk_java_files from the default upstream
+ (eg. OpenJDK8u121-b13) to a new directory, for easy directory comparison
+ using e.g. kdiff3, which allows inspecting detailed diffs.
+ - The ANDROID_BUILD_TOP environment variable must be set to point to the
+ AOSP root directory (parent of libcore).
+ - Run with -h command line argument to get usage instructions.
+
+To check out upstreams OpenJDK 7u40, 8u60 and 8u121-b13, run:
+
+mkdir openjdk
+cd openjdk
+hg clone http://hg.openjdk.java.net/jdk7u/jdk7u40/ 7u40
+(cd !$ ; sh get_source.sh)
+hg clone http://hg.openjdk.java.net/jdk8u/jdk8u 8u121-b13
+(cd !$ ; hg update -r jdk8u121-b13 && sh get_source.sh)
+hg clone http://hg.openjdk.java.net/jdk8u/jdk8u60/ 8u60
+(cd !$ ; sh get_source.sh)
+
+The newly created openjdk directory is then a suitable argument for the
+--upstream_root parameter.
+"""
+
+import argparse
+import csv
+import filecmp
+import os
+import re
+import shutil
+import sys
+
+def rel_paths_from_makefile(build_top):
+ """Returns the list of relative paths to .java files parsed from openjdk_java_files.mk"""
+ list_file = os.path.join(build_top, "libcore", "openjdk_java_files.mk")
+
+ result = []
+ with open(list_file, "r") as f:
+ for line in f:
+ match = re.match("\s+ojluni/src/main/java/(.+\.java)\s*\\\s*", line)
+ if match:
+ path = match.group(1)
+ # convert / to the appropriate separator (e.g. \ on Windows), just in case
+ path = os.path.normpath(path)
+ result.append(path)
+ return result
+
+def ojluni_path(build_top, rel_path):
+ """The full path of the file at the given rel_path in ojluni"""
+ return os.path.join(build_top, "libcore", "ojluni", "src", "main", "java", rel_path)
+
+def upstream_path(upstream_root, upstream, rel_path):
+ """The full path of the file at the given rel_path in the given upstream"""
+ source_dirs = [
+ "jdk/src/share/classes",
+ "jdk/src/solaris/classes"
+ ]
+ for source_dir in source_dirs:
+ source_dir = os.path.normpath(source_dir)
+ result = os.path.join(upstream_root, upstream, source_dir, rel_path)
+ if os.path.exists(result):
+ return result
+ return None
+
+
+# For files with N and M lines, respectively, this runs in time
+# O(N+M) if the files are identical or O(N*M) if not. This could
+# be improved to O(D*(N+M)) for files with at most D lines
+# difference by only considering array elements within D cells
+# from the diagonal.
+def edit_distance_lines(file_a, file_b):
+ """
+ Computes the line-based edit distance between two text files, i.e.
+ the smallest number of line deletions, additions or replacements
+ that would transform the content of one file into that of the other.
+ """
+ if filecmp.cmp(file_a, file_b, shallow=False):
+ return 0 # files identical
+ with open(file_a) as f:
+ lines_a = f.readlines()
+ with open(file_b) as f:
+ lines_b = f.readlines()
+ prev_cost = range(0, len(lines_b) + 1)
+ for end_a in range(1, len(lines_a) + 1):
+ # For each valid index i, prev_cost[i] is the edit distance between
+ # lines_a[:end_a-1] and lines_b[:i].
+ # We now calculate cur_cost[end_b] as the edit distance between
+ # line_a[:end_a] and lines_b[:end_b]
+ cur_cost = [end_a]
+ for end_b in range(1, len(lines_b) + 1):
+ c = min(
+ cur_cost[-1] + 1, # append line from b
+ prev_cost[end_b] + 1, # append line from a
+ # match or replace line
+ prev_cost[end_b - 1] + (0 if lines_a[end_a - 1] == lines_b[end_b - 1] else 1)
+ )
+ cur_cost.append(c)
+ prev_cost = cur_cost
+ return prev_cost[-1]
+
+def compare_to_upstreams_and_save(out_file, build_top, upstream_root, upstreams, rel_paths, best_only=False):
+ """
+ Prints tab-separated values comparing ojluni files vs. each
+ upstream, for each of the rel_paths, suitable for human
+ analysis in a spreadsheet.
+ This includes whether the corresponding upstream file is
+ missing, identical, or by how many lines it differs, and
+ a guess as to the correct upstream based on minimal line
+ difference (ties broken in favor of upstreams that occur
+ earlier in the list).
+ """
+ writer = csv.writer(out_file, delimiter='\t')
+ writer.writerow(["rel_path", "guessed_upstream"] + upstreams)
+ for rel_path in rel_paths:
+ ojluni_file = ojluni_path(build_top, rel_path)
+ upstream_comparisons = []
+ best_distance = sys.maxint
+ guessed_upstream = ""
+ for upstream in upstreams:
+ upstream_file = upstream_path(upstream_root, upstream, rel_path)
+ if upstream_file is None:
+ upstream_comparison = "missing"
+ else:
+ edit_distance = edit_distance_lines(upstream_file, ojluni_file)
+ if edit_distance == 0:
+ upstream_comparison = "identical"
+ else:
+ upstream_comparison = "different (%d lines)" % (edit_distance)
+ if edit_distance < best_distance:
+ best_distance = edit_distance
+ guessed_upstream = upstream
+ upstream_comparisons.append(upstream_comparison)
+ writer.writerow([rel_path, guessed_upstream ] + upstream_comparisons)
+
+def copy_files(rel_paths, upstream_root, upstream, output_dir):
+ """Copies files at the given rel_paths from upstream to output_dir"""
+ for rel_path in rel_paths:
+ upstream_file = upstream_path(upstream_root, upstream, rel_path)
+ if upstream_file is not None:
+ out_file = os.path.join(output_dir, rel_path)
+ out_dir = os.path.dirname(out_file)
+ if not os.path.exists(out_dir):
+ os.makedirs(out_dir)
+ shutil.copyfile(upstream_file, out_file)
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Check openjdk_java_files contents against upstream file contents.")
+ parser.add_argument("--upstream_root",
+ help="Path below where upstream sources are checked out. This should be a "
+ "directory with one child directory for each upstream (select the "
+ "upstreams to compare against via --upstreams).",
+ required=True,)
+ parser.add_argument("--upstreams",
+ default="8u121-b13,8u60,7u40",
+ help="Comma separated list of subdirectory names of --upstream_root that "
+ "each hold one upstream.")
+ parser.add_argument("--output_dir",
+ help="(optional) path where default upstream sources should be copied to; "
+ "this path must not yet exist and will be created. "
+ "The default upstream is the one that occurs first in --upstreams.")
+ parser.add_argument("--build_top",
+ default=os.environ.get('ANDROID_BUILD_TOP'),
+ help="Path where Android sources are checked out (defaults to $ANDROID_BUILD_TOP).")
+ args = parser.parse_args()
+ if args.output_dir is not None and os.path.exists(args.output_dir):
+ raise Exception("Output dir already exists: " + args.output_dir)
+
+ upstreams = [upstream.strip() for upstream in args.upstreams.split(',')]
+ default_upstream = upstreams[0]
+ for upstream in upstreams:
+ upstream_path = os.path.join(args.upstream_root, upstream)
+ if not os.path.exists(upstream_path):
+ raise Exception("Upstream not found: " + upstream_path)
+
+ rel_paths = rel_paths_from_makefile(args.build_top)
+
+ compare_to_upstreams_and_save(
+ sys.stdout, args.build_top, args.upstream_root, upstreams, rel_paths)
+
+ if args.output_dir is not None:
+ copy_files(rel_paths, args.upstream_root, default_upstream, args.output_dir)
+
+if __name__ == '__main__':
+ main()
diff --git a/tzdata/shared2/Android.mk b/tzdata/shared2/Android.mk
new file mode 100644
index 0000000..634386b
--- /dev/null
+++ b/tzdata/shared2/Android.mk
@@ -0,0 +1,46 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+# Library of support classes for tzdata updates. Used on-device for handling distros and for
+# testing.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_shared2
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_JAVA_LIBRARIES := core-oj core-libart
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Library of support classes for tzdata updates. Used on host for host-side tests.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_shared2-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Tests for tzdata_update2 code
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_shared2-tests
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/test)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_STATIC_JAVA_LIBRARIES := tzdata_shared2 junit
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/DistroException.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroException.java
similarity index 96%
rename from tzdata/update2/src/main/libcore/tzdata/update2/DistroException.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/DistroException.java
index d83e473..d989486 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/DistroException.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
/**
* A checked exception used in connection with time zone distro creation / installation.
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/DistroVersion.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroVersion.java
similarity index 95%
rename from tzdata/update2/src/main/libcore/tzdata/update2/DistroVersion.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/DistroVersion.java
index 4848db7..80f37bc 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/DistroVersion.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroVersion.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
@@ -63,7 +63,7 @@
* The length of a well-formed distro version file:
* {Distro version}|{Rule version}|{Revision}
*/
- static final int DISTRO_VERSION_FILE_LENGTH = FORMAT_VERSION_STRING_LENGTH + 1
+ public static final int DISTRO_VERSION_FILE_LENGTH = FORMAT_VERSION_STRING_LENGTH + 1
+ RULES_VERSION_LENGTH
+ 1 + REVISION_LENGTH;
@@ -152,6 +152,15 @@
}
@Override
+ public int hashCode() {
+ int result = formatMajorVersion;
+ result = 31 * result + formatMinorVersion;
+ result = 31 * result + rulesVersion.hashCode();
+ result = 31 * result + revision;
+ return result;
+ }
+
+ @Override
public String toString() {
return "DistroVersion{" +
"formatMajorVersion=" + formatMajorVersion +
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/FileUtils.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/FileUtils.java
similarity index 94%
rename from tzdata/update2/src/main/libcore/tzdata/update2/FileUtils.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/FileUtils.java
index 3d9a73a..39626ac 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/FileUtils.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/FileUtils.java
@@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
@@ -173,4 +175,14 @@
return toReturn;
}
}
+
+ /**
+ * Creates an empty file.
+ *
+ * @param file the file to create
+ * @throws IOException if the file cannot be created
+ */
+ public static void createEmptyFile(File file) throws IOException {
+ new FileOutputStream(file, false /* append */).close();
+ }
}
diff --git a/tzdata/shared2/src/main/libcore/tzdata/shared2/StagedDistroOperation.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/StagedDistroOperation.java
new file mode 100644
index 0000000..0492e12
--- /dev/null
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/StagedDistroOperation.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.tzdata.shared2;
+
+/**
+ * Information about a staged time zone distro operation.
+ */
+public class StagedDistroOperation {
+
+ private static final StagedDistroOperation UNINSTALL_STAGED =
+ new StagedDistroOperation(true /* isUninstall */, null /* stagedVersion */);
+
+ public final boolean isUninstall;
+ public final DistroVersion distroVersion;
+
+ private StagedDistroOperation(boolean isUninstall, DistroVersion distroVersion) {
+ this.isUninstall = isUninstall;
+ this.distroVersion = distroVersion;
+ }
+
+ public static StagedDistroOperation install(DistroVersion distroVersion) {
+ if (distroVersion == null) {
+ throw new NullPointerException("distroVersion==null");
+ }
+ return new StagedDistroOperation(false /* isUninstall */, distroVersion);
+ }
+
+ public static StagedDistroOperation uninstall() {
+ return UNINSTALL_STAGED;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ StagedDistroOperation that = (StagedDistroOperation) o;
+
+ if (isUninstall != that.isUninstall) {
+ return false;
+ }
+ return distroVersion != null ? distroVersion.equals(that.distroVersion)
+ : that.distroVersion == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (isUninstall ? 1 : 0);
+ result = 31 * result + (distroVersion != null ? distroVersion.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "StagedDistroOperation{" +
+ "isUninstall=" + isUninstall +
+ ", distroVersion=" + distroVersion +
+ '}';
+ }
+}
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistro.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/TimeZoneDistro.java
similarity index 99%
rename from tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistro.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/TimeZoneDistro.java
index 04e3f2a..dd01fb0 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistro.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/TimeZoneDistro.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/DistroVersionTest.java b/tzdata/shared2/src/test/libcore/tzdata/shared2/DistroVersionTest.java
similarity index 98%
rename from tzdata/update2/src/test/libcore/tzdata/update2/DistroVersionTest.java
rename to tzdata/shared2/src/test/libcore/tzdata/shared2/DistroVersionTest.java
index 79ba9d8..5d3df3f 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/DistroVersionTest.java
+++ b/tzdata/shared2/src/test/libcore/tzdata/shared2/DistroVersionTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
import junit.framework.TestCase;
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/FileUtilsTest.java b/tzdata/shared2/src/test/libcore/tzdata/shared2/FileUtilsTest.java
similarity index 91%
rename from tzdata/update2/src/test/libcore/tzdata/update2/FileUtilsTest.java
rename to tzdata/shared2/src/test/libcore/tzdata/shared2/FileUtilsTest.java
index 470d1c1..87e6e6e 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/FileUtilsTest.java
+++ b/tzdata/shared2/src/test/libcore/tzdata/shared2/FileUtilsTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
import junit.framework.TestCase;
@@ -253,6 +253,43 @@
assertTrue(Arrays.equals(contents, exhaustedFileRead));
}
+ public void testCreateEmptyFile() throws Exception {
+ File dir = createTempDir();
+ File file = new File(dir, "one");
+ assertFalse(file.exists());
+ FileUtils.createEmptyFile(file);
+ assertTrue(file.exists());
+ assertEquals(0, file.length());
+ }
+
+ public void testCreateEmptyFile_isDir() throws Exception {
+ File dir = createTempDir();
+ assertTrue(dir.exists());
+ assertTrue(dir.isDirectory());
+
+ try {
+ FileUtils.createEmptyFile(dir);
+ } catch (FileNotFoundException expected) {
+ }
+ assertTrue(dir.exists());
+ assertTrue(dir.isDirectory());
+ }
+
+ public void testCreateEmptyFile_truncatesExisting() throws Exception {
+ File dir = createTempDir();
+ File file = new File(dir, "one");
+
+ try (FileOutputStream fos = new FileOutputStream(file)) {
+ fos.write(new byte[1000]);
+ }
+ assertTrue(file.exists());
+ assertEquals(1000, file.length());
+
+ FileUtils.createEmptyFile(file);
+ assertTrue(file.exists());
+ assertEquals(0, file.length());
+ }
+
private File createFile(byte[] contents) throws IOException {
File file = File.createTempFile(getClass().getSimpleName(), ".txt");
try (FileOutputStream fos = new FileOutputStream(file)) {
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroTest.java b/tzdata/shared2/src/test/libcore/tzdata/shared2/TimeZoneDistroTest.java
similarity index 99%
rename from tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroTest.java
rename to tzdata/shared2/src/test/libcore/tzdata/shared2/TimeZoneDistroTest.java
index dad1cc4..e5b6a17 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroTest.java
+++ b/tzdata/shared2/src/test/libcore/tzdata/shared2/TimeZoneDistroTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
import junit.framework.TestCase;
diff --git a/tzdata/testing/Android.mk b/tzdata/testing/Android.mk
index f6b9b3c..d86255b 100644
--- a/tzdata/testing/Android.mk
+++ b/tzdata/testing/Android.mk
@@ -25,6 +25,15 @@
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
+# Library of test-support classes for tzdata updates. Shared between CTS and other tests.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata-testing-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_JAVA_LIBRARY)
+
# Host version of the above library. For libcore host testing.
include $(CLEAR_VARS)
LOCAL_MODULE := tzdata-testing-hostdex
diff --git a/tzdata/tools2/Android.mk b/tzdata/tools2/Android.mk
index 7789700..f91fc6a 100644
--- a/tzdata/tools2/Android.mk
+++ b/tzdata/tools2/Android.mk
@@ -14,14 +14,23 @@
LOCAL_PATH:= $(call my-dir)
-# Library of tools classes for tzdata updates. Not required on device, except in tests.
+# Library of tools classes for tzdata updates. Only used in tests.
include $(CLEAR_VARS)
LOCAL_MODULE := tzdata_tools2
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
LOCAL_JAVACFLAGS := -encoding UTF-8
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
+LOCAL_JAVA_LIBRARIES := core-oj core-libart tzdata_shared2
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Library of tools classes for tzdata updates. Used when generating distros and in host-side tests.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_tools2-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_JAVA_LIBRARIES := tzdata_shared2-host
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tzdata/tools2/createTimeZoneDistro.sh b/tzdata/tools2/createTimeZoneDistro.sh
index 7e103e7..dc76c3d 100755
--- a/tzdata/tools2/createTimeZoneDistro.sh
+++ b/tzdata/tools2/createTimeZoneDistro.sh
@@ -5,23 +5,19 @@
# Usage: ./createTimeZoneDistro.sh <tzupdate.properties file> <output file>
# See libcore.tzdata.update2.tools.CreateTimeZoneDistro for more information.
-TOOLS_DIR=src/main/libcore/tzdata/update2/tools
-UPDATE_DIR=../update2/src/main/libcore/tzdata/update2
-GEN_DIR=./gen
-
# Fail if anything below fails
set -e
-rm -rf ${GEN_DIR}
-mkdir -p ${GEN_DIR}
+if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
+ echo "Configure your environment with build/envsetup.sh and lunch"
+ exit 1
+fi
-javac \
- ${TOOLS_DIR}/CreateTimeZoneDistro.java \
- ${TOOLS_DIR}/TimeZoneDistroBuilder.java \
- ${UPDATE_DIR}/DistroException.java \
- ${UPDATE_DIR}/DistroVersion.java \
- ${UPDATE_DIR}/FileUtils.java \
- ${UPDATE_DIR}/TimeZoneDistro.java \
- -d ${GEN_DIR}
+cd ${ANDROID_BUILD_TOP}
+make tzdata_tools2-host
-java -cp ${GEN_DIR} libcore.tzdata.update2.tools.CreateTimeZoneDistro $@
+TOOLS_LIB=${ANDROID_BUILD_TOP}/out/host/common/obj/JAVA_LIBRARIES/tzdata_tools2-host_intermediates/javalib.jar
+SHARED_LIB=${ANDROID_BUILD_TOP}/out/host/common/obj/JAVA_LIBRARIES/tzdata_shared2-host_intermediates/javalib.jar
+
+cd -
+java -cp ${TOOLS_LIB}:${SHARED_LIB} libcore.tzdata.update2.tools.CreateTimeZoneDistro $@
diff --git a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java
index b2b3fa4..4b70152 100644
--- a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java
+++ b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java
@@ -23,8 +23,8 @@
import java.io.OutputStream;
import java.io.Reader;
import java.util.Properties;
-import libcore.tzdata.update2.DistroVersion;
-import libcore.tzdata.update2.TimeZoneDistro;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.TimeZoneDistro;
/**
* A command-line tool for creating a timezone update distro.
diff --git a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java
index 6577401..4c12e96 100644
--- a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java
+++ b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java
@@ -21,9 +21,9 @@
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-import libcore.tzdata.update2.DistroException;
-import libcore.tzdata.update2.DistroVersion;
-import libcore.tzdata.update2.TimeZoneDistro;
+import libcore.tzdata.shared2.DistroException;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.TimeZoneDistro;
/**
* A class for creating a {@link TimeZoneDistro} containing timezone update data. Used in real
diff --git a/tzdata/update2/Android.mk b/tzdata/update2/Android.mk
index 9e32862..0e197ba 100644
--- a/tzdata/update2/Android.mk
+++ b/tzdata/update2/Android.mk
@@ -14,13 +14,13 @@
LOCAL_PATH:= $(call my-dir)
-# Library of support classes for tzdata updates. Shared between update generation and
-# on-device code.
+# The classes needed to handle installation of time zone updates.
include $(CLEAR_VARS)
LOCAL_MODULE := tzdata_update2
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_JAVA_LIBRARIES := tzdata_shared2
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
@@ -30,6 +30,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src/test)
LOCAL_JAVACFLAGS := -encoding UTF-8
-LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2 tzdata_tools2 tzdata-testing junit
+LOCAL_STATIC_JAVA_LIBRARIES := tzdata_shared2 tzdata_update2 tzdata_tools2 tzdata-testing junit
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
index 1b56ebf..e1ed794 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
+++ b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
@@ -20,45 +20,67 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import libcore.tzdata.shared2.DistroException;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.FileUtils;
+import libcore.tzdata.shared2.StagedDistroOperation;
+import libcore.tzdata.shared2.TimeZoneDistro;
import libcore.util.ZoneInfoDB;
/**
* A distro-validation / extraction class. Separate from the services code that uses it for easier
* testing. This class is not thread-safe: callers are expected to handle mutual exclusion.
*/
-public final class TimeZoneDistroInstaller {
- /** {@link #installWithErrorCode(byte[])} result code: Success. */
+public class TimeZoneDistroInstaller {
+ /** {@link #stageInstallWithErrorCode(byte[])} result code: Success. */
public final static int INSTALL_SUCCESS = 0;
- /** {@link #installWithErrorCode(byte[])} result code: Distro corrupt. */
+ /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro corrupt. */
public final static int INSTALL_FAIL_BAD_DISTRO_STRUCTURE = 1;
- /** {@link #installWithErrorCode(byte[])} result code: Distro version incompatible. */
+ /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro version incompatible. */
public final static int INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION = 2;
- /** {@link #installWithErrorCode(byte[])} result code: Distro rules too old for device. */
+ /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro rules too old for device. */
public final static int INSTALL_FAIL_RULES_TOO_OLD = 3;
- /** {@link #installWithErrorCode(byte[])} result code: Distro content failed validation. */
+ /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro content failed validation. */
public final static int INSTALL_FAIL_VALIDATION_ERROR = 4;
+ // This constant must match one in system/core/tzdatacheck.cpp.
+ private static final String STAGED_TZ_DATA_DIR_NAME = "staged";
+ // This constant must match one in system/core/tzdatacheck.cpp.
private static final String CURRENT_TZ_DATA_DIR_NAME = "current";
private static final String WORKING_DIR_NAME = "working";
private static final String OLD_TZ_DATA_DIR_NAME = "old";
+ /**
+ * The name of the file in the staged directory used to indicate a staged uninstallation.
+ */
+ // This constant must match one in system/core/tzdatacheck.cpp.
+ // VisibleForTesting.
+ public static final String UNINSTALL_TOMBSTONE_FILE_NAME = "STAGED_UNINSTALL_TOMBSTONE";
+
private final String logTag;
private final File systemTzDataFile;
- private final File oldTzDataDir;
+ private final File oldStagedDataDir;
+ private final File stagedTzDataDir;
private final File currentTzDataDir;
private final File workingDir;
public TimeZoneDistroInstaller(String logTag, File systemTzDataFile, File installDir) {
this.logTag = logTag;
this.systemTzDataFile = systemTzDataFile;
- oldTzDataDir = new File(installDir, OLD_TZ_DATA_DIR_NAME);
+ oldStagedDataDir = new File(installDir, OLD_TZ_DATA_DIR_NAME);
+ stagedTzDataDir = new File(installDir, STAGED_TZ_DATA_DIR_NAME);
currentTzDataDir = new File(installDir, CURRENT_TZ_DATA_DIR_NAME);
workingDir = new File(installDir, WORKING_DIR_NAME);
}
// VisibleForTesting
- File getOldTzDataDir() {
- return oldTzDataDir;
+ File getOldStagedDataDir() {
+ return oldStagedDataDir;
+ }
+
+ // VisibleForTesting
+ File getStagedTzDataDir() {
+ return stagedTzDataDir;
}
// VisibleForTesting
@@ -72,34 +94,35 @@
}
/**
- * Install the supplied content.
+ * Stage an install of the supplied content, to be installed the next time the device boots.
*
- * <p>Errors during unpacking or installation will throw an {@link IOException}.
+ * <p>Errors during unpacking or staging will throw an {@link IOException}.
* If the distro content is invalid this method returns {@code false}.
* If the installation completed successfully this method returns {@code true}.
*/
public boolean install(byte[] content) throws IOException {
- int result = installWithErrorCode(content);
+ int result = stageInstallWithErrorCode(content);
return result == INSTALL_SUCCESS;
}
/**
- * Install the supplied time zone distro.
+ * Stage an install of the supplied content, to be installed the next time the device boots.
*
- * <p>Errors during unpacking or installation will throw an {@link IOException}.
+ * <p>Errors during unpacking or staging will throw an {@link IOException}.
* Returns {@link #INSTALL_SUCCESS} or an error code.
*/
- public int installWithErrorCode(byte[] content) throws IOException {
- if (oldTzDataDir.exists()) {
- FileUtils.deleteRecursive(oldTzDataDir);
+ public int stageInstallWithErrorCode(byte[] content) throws IOException {
+ if (oldStagedDataDir.exists()) {
+ FileUtils.deleteRecursive(oldStagedDataDir);
}
if (workingDir.exists()) {
FileUtils.deleteRecursive(workingDir);
}
Slog.i(logTag, "Unpacking / verifying time zone update");
- unpackDistro(content, workingDir);
try {
+ unpackDistro(content, workingDir);
+
DistroVersion distroVersion;
try {
distroVersion = readDistroVersion(workingDir);
@@ -147,52 +170,78 @@
Slog.i(logTag, "Applying time zone update");
FileUtils.makeDirectoryWorldAccessible(workingDir);
- if (currentTzDataDir.exists()) {
- Slog.i(logTag, "Moving " + currentTzDataDir + " to " + oldTzDataDir);
- FileUtils.rename(currentTzDataDir, oldTzDataDir);
+ // Check if there is already a staged install or uninstall and remove it if there is.
+ if (!stagedTzDataDir.exists()) {
+ Slog.i(logTag, "Nothing to unstage at " + stagedTzDataDir);
+ } else {
+ Slog.i(logTag, "Moving " + stagedTzDataDir + " to " + oldStagedDataDir);
+ // Move stagedTzDataDir out of the way in one operation so we can't partially delete
+ // the contents.
+ FileUtils.rename(stagedTzDataDir, oldStagedDataDir);
}
- Slog.i(logTag, "Moving " + workingDir + " to " + currentTzDataDir);
- FileUtils.rename(workingDir, currentTzDataDir);
- Slog.i(logTag, "Update applied: " + currentTzDataDir + " successfully created");
+
+ // Move the workingDir to be the new staged directory.
+ Slog.i(logTag, "Moving " + workingDir + " to " + stagedTzDataDir);
+ FileUtils.rename(workingDir, stagedTzDataDir);
+ Slog.i(logTag, "Install staged: " + stagedTzDataDir + " successfully created");
return INSTALL_SUCCESS;
} finally {
- deleteBestEffort(oldTzDataDir);
+ deleteBestEffort(oldStagedDataDir);
deleteBestEffort(workingDir);
}
}
/**
- * Uninstall the current timezone update in /data, returning the device to using data from
- * /system. Returns {@code true} if uninstallation was successful, {@code false} if there was
- * nothing installed in /data to uninstall.
+ * Stage an uninstall of the current timezone update in /data which, on reboot, will return the
+ * device to using data from /system. Returns {@code true} if staging the uninstallation was
+ * successful, {@code false} if there was nothing installed in /data to uninstall. If there was
+ * something else staged it will be replaced by this call.
*
* <p>Errors encountered during uninstallation will throw an {@link IOException}.
*/
- public boolean uninstall() throws IOException {
+ public boolean stageUninstall() throws IOException {
Slog.i(logTag, "Uninstalling time zone update");
- // Make sure we don't have a dir where we're going to move the currently installed data to.
- if (oldTzDataDir.exists()) {
+ if (oldStagedDataDir.exists()) {
// If we can't remove this, an exception is thrown and we don't continue.
- FileUtils.deleteRecursive(oldTzDataDir);
+ FileUtils.deleteRecursive(oldStagedDataDir);
+ }
+ if (workingDir.exists()) {
+ FileUtils.deleteRecursive(workingDir);
}
- if (!currentTzDataDir.exists()) {
- Slog.i(logTag, "Nothing to uninstall at " + currentTzDataDir);
- return false;
+ try {
+ // Check if there is already an install or uninstall staged and remove it.
+ if (!stagedTzDataDir.exists()) {
+ Slog.i(logTag, "Nothing to unstage at " + stagedTzDataDir);
+ } else {
+ Slog.i(logTag, "Moving " + stagedTzDataDir + " to " + oldStagedDataDir);
+ // Move stagedTzDataDir out of the way in one operation so we can't partially delete
+ // the contents.
+ FileUtils.rename(stagedTzDataDir, oldStagedDataDir);
+ }
+
+ // If there's nothing actually installed, there's nothing to uninstall so no need to
+ // stage anything.
+ if (!currentTzDataDir.exists()) {
+ Slog.i(logTag, "Nothing to uninstall at " + currentTzDataDir);
+ return false;
+ }
+
+ // Stage an uninstall in workingDir.
+ FileUtils.ensureDirectoriesExist(workingDir, true /* makeWorldReadable */);
+ FileUtils.createEmptyFile(new File(workingDir, UNINSTALL_TOMBSTONE_FILE_NAME));
+
+ // Move the workingDir to be the new staged directory.
+ Slog.i(logTag, "Moving " + workingDir + " to " + stagedTzDataDir);
+ FileUtils.rename(workingDir, stagedTzDataDir);
+ Slog.i(logTag, "Uninstall staged: " + stagedTzDataDir + " successfully created");
+
+ return true;
+ } finally {
+ deleteBestEffort(oldStagedDataDir);
+ deleteBestEffort(workingDir);
}
-
- Slog.i(logTag, "Moving " + currentTzDataDir + " to " + oldTzDataDir);
- // Move currentTzDataDir out of the way in one operation so we can't partially delete
- // the contents, which would leave a partial install.
- FileUtils.rename(currentTzDataDir, oldTzDataDir);
-
- // Do our best to delete the now uninstalled timezone data.
- deleteBestEffort(oldTzDataDir);
-
- Slog.i(logTag, "Time zone update uninstalled.");
-
- return true;
}
/**
@@ -210,6 +259,24 @@
}
/**
+ * Reads information about any currently staged distro operation. Returns {@code null} if there
+ * is no distro operation staged.
+ *
+ * @throws IOException if there was a problem reading data from /data
+ * @throws DistroException if there was a problem with the staged distro format/structure
+ */
+ public StagedDistroOperation getStagedDistroOperation() throws DistroException, IOException {
+ if (!stagedTzDataDir.exists()) {
+ return null;
+ }
+ if (new File(stagedTzDataDir, UNINSTALL_TOMBSTONE_FILE_NAME).exists()) {
+ return StagedDistroOperation.uninstall();
+ } else {
+ return StagedDistroOperation.install(readDistroVersion(stagedTzDataDir));
+ }
+ }
+
+ /**
* Reads the timezone rules version present in /system. i.e. the version that would be present
* after a factory reset.
*
@@ -246,8 +313,7 @@
private DistroVersion readDistroVersion(File distroDir) throws DistroException, IOException {
Slog.i(logTag, "Reading distro format version");
- File distroVersionFile =
- new File(distroDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+ File distroVersionFile = new File(distroDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
if (!distroVersionFile.exists()) {
throw new DistroException("No distro version file found: " + distroVersionFile);
}
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java b/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
index 6ae0e56..cf40bf6 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
+++ b/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
@@ -30,9 +30,15 @@
import java.util.zip.ZipOutputStream;
import libcore.io.IoUtils;
import libcore.io.Streams;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.FileUtils;
+import libcore.tzdata.shared2.StagedDistroOperation;
+import libcore.tzdata.shared2.TimeZoneDistro;
import libcore.tzdata.testing.ZoneInfoTestHelper;
import libcore.tzdata.update2.tools.TimeZoneDistroBuilder;
+import static org.junit.Assert.assertArrayEquals;
+
/**
* Tests for {@link TimeZoneDistroInstaller}.
*/
@@ -87,100 +93,110 @@
}
/** Tests the an update on a device will fail if the /system tzdata file cannot be found. */
- public void testInstall_badSystemFile() throws Exception {
+ public void testStageInstallWithErrorCode_badSystemFile() throws Exception {
File doesNotExist = new File(testSystemTzDataDir, "doesNotExist");
TimeZoneDistroInstaller brokenSystemInstaller = new TimeZoneDistroInstaller(
"TimeZoneDistroInstallerTest", doesNotExist, testInstallDir);
TimeZoneDistro tzData = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
try {
- brokenSystemInstaller.installWithErrorCode(tzData.getBytes());
+ brokenSystemInstaller.stageInstallWithErrorCode(tzData.getBytes());
fail();
} catch (IOException expected) {}
- assertNoContentInstalled();
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
/** Tests the first successful update on a device */
- public void testInstall_successfulFirstUpdate() throws Exception {
+ public void testStageInstallWithErrorCode_successfulFirstUpdate() throws Exception {
TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(distro.getBytes()));
- assertDistroInstalled(distro);
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertInstallDistroStaged(distro);
+ assertNoInstalledDistro();
}
/**
* Tests we can install an update the same version as is in /system.
*/
- public void testInstall_successfulFirstUpdate_sameVersionAsSystem() throws Exception {
+ public void testStageInstallWithErrorCode_successfulFirstUpdate_sameVersionAsSystem()
+ throws Exception {
TimeZoneDistro distro = createValidTimeZoneDistro(SYSTEM_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(distro.getBytes()));
- assertDistroInstalled(distro);
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertInstallDistroStaged(distro);
+ assertNoInstalledDistro();
}
/**
* Tests we cannot install an update older than the version in /system.
*/
- public void testInstall_unsuccessfulFirstUpdate_olderVersionThanSystem() throws Exception {
+ public void testStageInstallWithErrorCode_unsuccessfulFirstUpdate_olderVersionThanSystem()
+ throws Exception {
TimeZoneDistro distro = createValidTimeZoneDistro(OLDER_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD,
- installer.installWithErrorCode(distro.getBytes()));
- assertNoContentInstalled();
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
/**
- * Tests an update on a device when there is a prior update already applied.
+ * Tests an update on a device when there is a prior update already staged.
*/
- public void testInstall_successfulFollowOnUpdate_newerVersion() throws Exception {
+ public void testStageInstallWithErrorCode_successfulFollowOnUpdate_newerVersion()
+ throws Exception {
TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(distro1.getBytes()));
- assertDistroInstalled(distro1);
+ installer.stageInstallWithErrorCode(distro1.getBytes()));
+ assertInstallDistroStaged(distro1);
TimeZoneDistro distro2 = createValidTimeZoneDistro(NEW_RULES_VERSION, 2);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(distro2.getBytes()));
- assertDistroInstalled(distro2);
+ installer.stageInstallWithErrorCode(distro2.getBytes()));
+ assertInstallDistroStaged(distro2);
TimeZoneDistro distro3 = createValidTimeZoneDistro(NEWER_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(distro3.getBytes()));
- assertDistroInstalled(distro3);
+ installer.stageInstallWithErrorCode(distro3.getBytes()));
+ assertInstallDistroStaged(distro3);
+ assertNoInstalledDistro();
}
/**
* Tests an update on a device when there is a prior update already applied, but the follow
* on update is older than in /system.
*/
- public void testInstall_unsuccessfulFollowOnUpdate_olderVersion() throws Exception {
+ public void testStageInstallWithErrorCode_unsuccessfulFollowOnUpdate_olderVersion()
+ throws Exception {
TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 2);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(distro1.getBytes()));
- assertDistroInstalled(distro1);
+ installer.stageInstallWithErrorCode(distro1.getBytes()));
+ assertInstallDistroStaged(distro1);
TimeZoneDistro distro2 = createValidTimeZoneDistro(OLDER_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD,
- installer.installWithErrorCode(distro2.getBytes()));
- assertDistroInstalled(distro1);
+ installer.stageInstallWithErrorCode(distro2.getBytes()));
+ assertInstallDistroStaged(distro1);
+ assertNoInstalledDistro();
}
/** Tests that a distro with a missing file will not update the content. */
- public void testInstall_missingTzDataFile() throws Exception {
- TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+ public void testStageInstallWithErrorCode_missingTzDataFile() throws Exception {
+ TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(installedDistro.getBytes()));
- assertDistroInstalled(installedDistro);
+ installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+ assertInstallDistroStaged(stagedDistro);
TimeZoneDistro incompleteDistro =
createValidTimeZoneDistroBuilder(NEWER_RULES_VERSION, 1)
@@ -188,17 +204,18 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.installWithErrorCode(incompleteDistro.getBytes()));
- assertDistroInstalled(installedDistro);
+ installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+ assertInstallDistroStaged(stagedDistro);
+ assertNoInstalledDistro();
}
/** Tests that a distro with a missing file will not update the content. */
- public void testInstall_missingIcuFile() throws Exception {
- TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+ public void testStageInstallWithErrorCode_missingIcuFile() throws Exception {
+ TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(installedDistro.getBytes()));
- assertDistroInstalled(installedDistro);
+ installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+ assertInstallDistroStaged(stagedDistro);
TimeZoneDistro incompleteDistro =
createValidTimeZoneDistroBuilder(NEWER_RULES_VERSION, 1)
@@ -206,14 +223,15 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.installWithErrorCode(incompleteDistro.getBytes()));
- assertDistroInstalled(installedDistro);
+ installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+ assertInstallDistroStaged(stagedDistro);
+ assertNoInstalledDistro();
}
/**
* Tests that an update will be unpacked even if there is a partial update from a previous run.
*/
- public void testInstall_withWorkingDir() throws Exception {
+ public void testStageInstallWithErrorCode_withWorkingDir() throws Exception {
File workingDir = installer.getWorkingDir();
assertTrue(workingDir.mkdir());
createFile(new File(workingDir, "myFile"), new byte[] { 'a' });
@@ -221,42 +239,45 @@
TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.installWithErrorCode(distro.getBytes()));
- assertDistroInstalled(distro);
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertInstallDistroStaged(distro);
+ assertNoInstalledDistro();
}
/**
* Tests that a distro without a distro version file will be rejected.
*/
- public void testInstall_withMissingDistroVersionFile() throws Exception {
+ public void testStageInstallWithErrorCode_withMissingDistroVersionFile() throws Exception {
// Create a distro without a version file.
TimeZoneDistro distro = createValidTimeZoneDistroBuilder(NEW_RULES_VERSION, 1)
.clearVersionForTests()
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.installWithErrorCode(distro.getBytes()));
- assertNoContentInstalled();
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
/**
* Tests that a distro with an newer distro version will be rejected.
*/
- public void testInstall_withNewerDistroVersion() throws Exception {
+ public void testStageInstallWithErrorCode_withNewerDistroVersion() throws Exception {
// Create a distro that will appear to be newer than the one currently supported.
TimeZoneDistro distro = createValidTimeZoneDistroBuilder(NEW_RULES_VERSION, 1)
.replaceFormatVersionForTests(2, 1)
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION,
- installer.installWithErrorCode(distro.getBytes()));
- assertNoContentInstalled();
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
/**
* Tests that a distro with a badly formed distro version will be rejected.
*/
- public void testInstall_withBadlyFormedDistroVersion() throws Exception {
+ public void testStageInstallWithErrorCode_withBadlyFormedDistroVersion() throws Exception {
// Create a distro that has an invalid major distro version. It should be 3 numeric
// characters, "." and 3 more numeric characters.
DistroVersion validDistroVersion = new DistroVersion(1, 1, NEW_RULES_VERSION, 1);
@@ -266,14 +287,15 @@
TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidFormatVersionBytes);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.installWithErrorCode(distro.getBytes()));
- assertNoContentInstalled();
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
/**
* Tests that a distro with a badly formed revision will be rejected.
*/
- public void testInstall_withBadlyFormedRevision() throws Exception {
+ public void testStageInstallWithErrorCode_withBadlyFormedRevision() throws Exception {
// Create a distro that has an invalid revision. It should be 3 numeric characters.
DistroVersion validDistroVersion = new DistroVersion(1, 1, NEW_RULES_VERSION, 1);
byte[] invalidRevisionBytes = validDistroVersion.toBytes();
@@ -282,14 +304,15 @@
TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidRevisionBytes);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.installWithErrorCode(distro.getBytes()));
- assertNoContentInstalled();
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
/**
* Tests that a distro with a badly formed rules version will be rejected.
*/
- public void testInstall_withBadlyFormedRulesVersion() throws Exception {
+ public void testStageInstallWithErrorCode_withBadlyFormedRulesVersion() throws Exception {
// Create a distro that has an invalid rules version. It should be in the form "2016c".
DistroVersion validDistroVersion = new DistroVersion(1, 1, NEW_RULES_VERSION, 1);
byte[] invalidRulesVersionBytes = validDistroVersion.toBytes();
@@ -298,38 +321,124 @@
TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidRulesVersionBytes);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.installWithErrorCode(distro.getBytes()));
- assertNoContentInstalled();
+ installer.stageInstallWithErrorCode(distro.getBytes()));
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
- public void testUninstall_noExistingDataDistro() throws Exception {
- assertFalse(installer.uninstall());
- assertNoContentInstalled();
+ public void testStageUninstall_noExistingDistro() throws Exception {
+ // To stage an uninstall, there would need to be installed rules.
+ assertFalse(installer.stageUninstall());
+
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
}
- public void testUninstall_existingDataDistro() throws Exception {
- File currentDataDir = installer.getCurrentTzDataDir();
- assertTrue(currentDataDir.mkdir());
+ public void testStageUninstall_existingStagedDataDistro() throws Exception {
+ // To stage an uninstall, we need to have some installed rules.
+ TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+ simulateInstalledDistro(installedDistro);
- assertTrue(installer.uninstall());
- assertNoContentInstalled();
+ File stagedDataDir = installer.getStagedTzDataDir();
+ assertTrue(stagedDataDir.mkdir());
+
+ assertTrue(installer.stageUninstall());
+ assertDistroUninstallStaged();
+ assertInstalledDistro(installedDistro);
}
- public void testUninstall_oldDirsAlreadyExists() throws Exception {
- File oldTzDataDir = installer.getOldTzDataDir();
- assertTrue(oldTzDataDir.mkdir());
+ public void testStageUninstall_oldDirsAlreadyExists() throws Exception {
+ // To stage an uninstall, we need to have some installed rules.
+ TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+ simulateInstalledDistro(installedDistro);
- File currentDataDir = installer.getCurrentTzDataDir();
- assertTrue(currentDataDir.mkdir());
+ File oldStagedDataDir = installer.getOldStagedDataDir();
+ assertTrue(oldStagedDataDir.mkdir());
- assertTrue(installer.uninstall());
- assertNoContentInstalled();
+ File workingDir = installer.getWorkingDir();
+ assertTrue(workingDir.mkdir());
+
+ assertTrue(installer.stageUninstall());
+
+ assertDistroUninstallStaged();
+ assertFalse(workingDir.exists());
+ assertFalse(oldStagedDataDir.exists());
+ assertInstalledDistro(installedDistro);
}
public void testGetSystemRulesVersion() throws Exception {
assertEquals(SYSTEM_RULES_VERSION, installer.getSystemRulesVersion());
}
+ public void testGetInstalledDistroVersion() throws Exception {
+ // Check result when nothing installed.
+ assertNull(installer.getInstalledDistroVersion());
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
+
+ // Now simulate there being an existing install active.
+ TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+ simulateInstalledDistro(distro);
+ assertInstalledDistro(distro);
+
+ // Check result when something installed.
+ assertEquals(distro.getDistroVersion(), installer.getInstalledDistroVersion());
+ assertNoDistroOperationStaged();
+ assertInstalledDistro(distro);
+ }
+
+ public void testGetStagedDistroOperation() throws Exception {
+ TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+ TimeZoneDistro distro2 = createValidTimeZoneDistro(NEWER_RULES_VERSION, 1);
+
+ // Check result when nothing staged.
+ assertNull(installer.getStagedDistroOperation());
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
+
+ // Check result after unsuccessfully staging an uninstall.
+ // Can't stage an uninstall without an installed distro.
+ assertFalse(installer.stageUninstall());
+ assertNull(installer.getStagedDistroOperation());
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
+
+ // Check result after staging an install.
+ assertTrue(installer.install(distro1.getBytes()));
+ StagedDistroOperation expectedStagedInstall =
+ StagedDistroOperation.install(distro1.getDistroVersion());
+ assertEquals(expectedStagedInstall, installer.getStagedDistroOperation());
+ assertInstallDistroStaged(distro1);
+ assertNoInstalledDistro();
+
+ // Check result after unsuccessfully staging an uninstall (but after removing a staged
+ // install). Can't stage an uninstall without an installed distro.
+ assertFalse(installer.stageUninstall());
+ assertNull(installer.getStagedDistroOperation());
+ assertNoDistroOperationStaged();
+ assertNoInstalledDistro();
+
+ // Now simulate there being an existing install active.
+ simulateInstalledDistro(distro1);
+ assertInstalledDistro(distro1);
+
+ // Check state after successfully staging an uninstall.
+ assertTrue(installer.stageUninstall());
+ StagedDistroOperation expectedStagedUninstall = StagedDistroOperation.uninstall();
+ assertEquals(expectedStagedUninstall, installer.getStagedDistroOperation());
+ assertDistroUninstallStaged();
+ assertInstalledDistro(distro1);
+
+ // Check state after successfully staging an install.
+ assertEquals(TimeZoneDistroInstaller.INSTALL_SUCCESS,
+ installer.stageInstallWithErrorCode(distro2.getBytes()));
+ StagedDistroOperation expectedStagedInstall2 =
+ StagedDistroOperation.install(distro2.getDistroVersion());
+ assertEquals(expectedStagedInstall2, installer.getStagedDistroOperation());
+ assertInstallDistroStaged(distro2);
+ assertInstalledDistro(distro1);
+ }
+
private static TimeZoneDistro createValidTimeZoneDistro(
String rulesVersion, int revision) throws Exception {
return createValidTimeZoneDistroBuilder(rulesVersion, revision).build();
@@ -351,24 +460,27 @@
.setIcuData(icuData);
}
- private void assertDistroInstalled(TimeZoneDistro expectedDistro) throws Exception {
+ private void assertInstallDistroStaged(TimeZoneDistro expectedDistro) throws Exception {
assertTrue(testInstallDir.exists());
- File currentTzDataDir = installer.getCurrentTzDataDir();
- assertTrue(currentTzDataDir.exists());
+ File stagedTzDataDir = installer.getStagedTzDataDir();
+ assertTrue(stagedTzDataDir.exists());
File distroVersionFile =
- new File(currentTzDataDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+ new File(stagedTzDataDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
assertTrue(distroVersionFile.exists());
- File bionicFile = new File(currentTzDataDir, TimeZoneDistro.TZDATA_FILE_NAME);
+ File bionicFile = new File(stagedTzDataDir, TimeZoneDistro.TZDATA_FILE_NAME);
assertTrue(bionicFile.exists());
- File icuFile = new File(currentTzDataDir, TimeZoneDistro.ICU_DATA_FILE_NAME);
+ File icuFile = new File(stagedTzDataDir, TimeZoneDistro.ICU_DATA_FILE_NAME);
assertTrue(icuFile.exists());
- // Assert getInstalledDistroVersion() is reporting correctly.
- assertEquals(expectedDistro.getDistroVersion(), installer.getInstalledDistroVersion());
+ // Assert getStagedDistroState() is reporting correctly.
+ StagedDistroOperation stagedDistroOperation = installer.getStagedDistroOperation();
+ assertNotNull(stagedDistroOperation);
+ assertFalse(stagedDistroOperation.isUninstall);
+ assertEquals(expectedDistro.getDistroVersion(), stagedDistroOperation.distroVersion);
try (ZipInputStream zis = new ZipInputStream(
new ByteArrayInputStream(expectedDistro.getBytes()))) {
@@ -398,23 +510,64 @@
throws Exception {
byte[] actualBytes = IoUtils.readFileAsByteArray(actual.getPath());
byte[] expectedBytes = Streams.readFullyNoClose(expected);
- assertTrue(Arrays.equals(expectedBytes, actualBytes));
+ assertArrayEquals(expectedBytes, actualBytes);
}
- private void assertNoContentInstalled() throws Exception {
- assertNull(installer.getInstalledDistroVersion());
+ private void assertNoDistroOperationStaged() throws Exception {
+ assertNull(installer.getStagedDistroOperation());
- File currentTzDataDir = installer.getCurrentTzDataDir();
- assertFalse(currentTzDataDir.exists());
+ File stagedTzDataDir = installer.getStagedTzDataDir();
+ assertFalse(stagedTzDataDir.exists());
// Also check no working directories are left lying around.
File workingDir = installer.getWorkingDir();
assertFalse(workingDir.exists());
- File oldDataDir = installer.getOldTzDataDir();
+ File oldDataDir = installer.getOldStagedDataDir();
assertFalse(oldDataDir.exists());
}
+ private void assertDistroUninstallStaged() throws Exception {
+ assertEquals(StagedDistroOperation.uninstall(), installer.getStagedDistroOperation());
+
+ File stagedTzDataDir = installer.getStagedTzDataDir();
+ assertTrue(stagedTzDataDir.exists());
+ assertTrue(stagedTzDataDir.isDirectory());
+
+ File uninstallTombstone =
+ new File(stagedTzDataDir, TimeZoneDistroInstaller.UNINSTALL_TOMBSTONE_FILE_NAME);
+ assertTrue(uninstallTombstone.exists());
+ assertTrue(uninstallTombstone.isFile());
+
+ // Also check no working directories are left lying around.
+ File workingDir = installer.getWorkingDir();
+ assertFalse(workingDir.exists());
+
+ File oldDataDir = installer.getOldStagedDataDir();
+ assertFalse(oldDataDir.exists());
+ }
+
+ private void simulateInstalledDistro(TimeZoneDistro timeZoneDistro) throws Exception {
+ File currentTzDataDir = installer.getCurrentTzDataDir();
+ assertFalse(currentTzDataDir.exists());
+ assertTrue(currentTzDataDir.mkdir());
+ timeZoneDistro.extractTo(currentTzDataDir);
+ }
+
+ private void assertNoInstalledDistro() {
+ assertFalse(installer.getCurrentTzDataDir().exists());
+ }
+
+ private void assertInstalledDistro(TimeZoneDistro timeZoneDistro) throws Exception {
+ File currentTzDataDir = installer.getCurrentTzDataDir();
+ assertTrue(currentTzDataDir.exists());
+ File versionFile = new File(currentTzDataDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+ assertTrue(versionFile.exists());
+ byte[] expectedVersionBytes = timeZoneDistro.getDistroVersion().toBytes();
+ byte[] actualVersionBytes = FileUtils.readBytes(versionFile, expectedVersionBytes.length);
+ assertArrayEquals(expectedVersionBytes, actualVersionBytes);
+ }
+
private static byte[] createTzData(String rulesVersion) {
return new ZoneInfoTestHelper.TzDataBuilder()
.initializeToValid()
diff --git a/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java b/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java
index 2348e43..2800037 100644
--- a/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java
+++ b/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java
@@ -39,6 +39,8 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import libcore.icu.ICU;
+import libcore.util.ZoneInfoDB;
public class MainActivity extends Activity implements View.OnClickListener {
@@ -67,6 +69,12 @@
requiredHashEditText = (EditText) findViewById(R.id.required_hash);
logView = (TextView) findViewById(R.id.log);
executor = Executors.newFixedThreadPool(1);
+ logString("Active libcore version: "
+ + ZoneInfoDB.getInstance().getVersion());
+ logString("Active icu4c version: "
+ + ICU.getTZDataVersion());
+ logString("Active icu4j version: "
+ + android.icu.util.TimeZone.getTZDataVersion());
}
@Override
@@ -147,9 +155,12 @@
private void logString(String value) {
logView.append(new Date() + " " + value + "\n");
- int scrollAmount =
- logView.getLayout().getLineTop(logView.getLineCount()) - logView.getHeight();
- logView.scrollTo(0, scrollAmount);
+ android.text.Layout layout = logView.getLayout();
+ if (layout != null) {
+ int scrollAmount =
+ layout.getLineTop(logView.getLineCount()) - logView.getHeight();
+ logView.scrollTo(0, scrollAmount);
+ }
}
private static String exceptionToString(Exception e) {